The JACK documentation postulates that the process() callback must not
block, therefore locking is forbidden. Anyway, the old code was racy.
Remove all locks, and don't wait for more data to become available -
just send to the port what is already in the buffer.
Added mpd.conf options for disabling automatic resamling, sample
format and channel conversion. This way, users may choose to override
ALSA's automatic resampling, and use libsamplerate instead.
If the sample format isn't supported by the device (i.e. 24 bit on
low-end sound chips), fall back to 16 bit output. There is code in
pcm_utils.c which converts PCM data to 16 bit.
Revert e4f5d6bd "re-enable-nonblocking, but sleep if busy".
Non-blocking mode with manual sleeping doesn't help at all (by the
way, the patch should have used snd_pcm_wait() instead of
my_usleep()). ALSA knows much more about the hardware quirks, so we
just let it do the job.
Leftover from the output API changes: oss_open_default() was changed
to return a void*, but it still returned "0" to report success.
Report the OssData pointer instead.
A frame contains one sample per channel, thus it is sample_size *
channels. This patch includes some cleanup for various locations
where the sample size for 24 bit audio was still 3 bytes (instead of
4).
Having an array with disabled entries sucks. Removed that
DISABLED_SHOUT_ENCODER_PLUGIN macro, and fill the plugin list only
with plugins which are actually enabled. This should be done for all
plugin types.
pause() puts the audio output into pause mode: if supported, it may
perform a special action, which keeps the device open, but does not
play anything. Output plugins like "shout" might want to play silence
during pause, so their clients won't be disconnected. Plugins which
do not support pausing will simply be closed, and have to be reopened
when unpaused.
This pach includes an implementation for the shout plugin, which
sends silence chunks.
The old struct initializers are error prone and don't allow moving
elements around. Since we are going to overhaul some of the APIs
soon, it's easier to have all implementations use C99 initializers.
Seeing the "mpd_" prefix _everywhere_ is mind-numbing as the
mind needs to retrain itself to skip over the first 4 tokens of
a type to get to its meaning. So avoid having extra characters
on my terminal to make it easier to follow code at 2:30 am in
the morning.
Please report any new issues you may come across on Free
toolchains. I realize how difficult it can be to build/maintain
cross-compiling toolchains and I have no intention of forcing
people to upgrade their toolchains to build mpd.
Tested with gcc 2.95.4 and and gcc 4.3.1 on x86-32.
We have eliminated direct accesses to the audio_output struct from
the all output plugins. Make it opaque for them, and move its real
declaration to output_internal.h, similar to decoder_internal.h.
Pass the opaque structure to plugin.init() only, which will return the
plugin's data pointer on success, and NULL on failure. This data
pointer will be passed to all other methods instead of the
audio_output struct.
The JACK output plugin needs to reset its "opened" flag when the JACK
server fails. To prevent it from accessing the audio_output struct
directly introduce the API function audio_output_closed().
Reduce direct accesses to the audio_output struct from the plugins:
this time, eliminate all accesses to audio_output.name. The name is
required by some plugins for log messages.
Pass the globally configured audio_format as a const pointer to
plugin.init(). plugin.open() gets a writable pointer which contains
the audio_format requested by the plugin. Its initial value is either
the configured audio_format or the input file's audio_format.
The inline function audio_format_sample_size() calculates how many
bytes each sample consumes. This function already takes into account
that 24 bit samples are 4 bytes long, not 3.
Instead of letting ALSA block for us (and potentially allowing
something stupid on certain hardware or drivers), we do the
sleeping ourselves. We calculate the sleep to be a fraction of
period_time to avoid oversleeping (and thus audible skipping).
Since the buffer size is known at compile time, we can save an
indirection by declaring it as a char array instead of a pointer.
That saves an extra allocation, and we can calculate with the
compile-time constant sizeof(data) instead of the attribute "max_len".
Shout encoder plugins are known at compile time. There is no reason
to use a complex data structure as "List" to manage them at runtime -
just put the pointers into a static array.
[mk: moved this patch after "Refactor and cleanup of shout Ogg and MP3
audio outputs". The original commit message follows, although it is
outdated:]
Creation of shout_mp3 audio output plugin. Basically I just copied the
existing shout plugin and replaced ogg with lame. Uses lame for mp3
encoding. Next step is to pull common functionality out of each shout
plugin and share it between them.
Configuration options for "shout_mp3" are the same as for "shout".
I've perhaps gone a bit overboard, but here's the current rundown:
Both Ogg and MP3 use the "shout" audio output plugin. The shout audio
output plugin itself has two new plugins, one for the Ogg encoder,
and another for the MP3 (LAME) encoder.
Configuration for an Ogg stream doesn't change. For an MP3 stream,
configuration is the same as Ogg, with two exceptions. First, you must
specify the optional "encoding" parameter, which should be set to "mp3".
See mpd.conf(5) for more details. Second, the "quality" parameter is
reversed for LAME, such that 1 is high quality for LAME, whereas 10 is
high quality for Ogg.
I've decomposed the code so that all libshout related operations
are done in audioOutput_shout.c, all Ogg specific functions are in
audioOutput_shout_ogg.c, and of course then all LAME specific functions
are handled in audioOutput_shout_mp3.c.
To develop encoder plugins for the shout audio output plugin, I basically
just mimicked the plugin system used for audio outputs. This might be
overkill, but hopefully if anyone ever wants to support some other sort
of stream, like maybe AAC, FLAC, or WMA (hey it could happen), they will
hopefully be all set.
The Ogg encoder is slightly less optimal under this configuration.
It used to send shout data directly out of its ogg_page structures. Now,
in the interest of encapsulation, it copies the data from its ogg_page
structures into a buffer provided by the shout audio output plugin (see
audioOutput_shout_ogg.c, line 77.) I suspect the performance impact
is negligible.
As for metadata, I'm pretty sure they'll both work. I wrote up a test
scaffold that would create a fake tag, and tell the plugin to send it
out to the stream every few seconds. It seemed to work fine. Of course,
if something does break, I'll be glad to fix it.
Lastly, I've renamed lots of things into snake_case, in keeping with
normalperson's wishes in that regard.
[mk: moved the MP3 patch after this one. Splitted this patch into
several parts; the others were already applied before this one. Fixed
a bunch GCC warnings and wrong whitespace modifications. Made it
compile with mpd-mk by adapting to its prototypes]
Support sending metadata to a shout server using shout_metadata_new()
and shout_metadata_add(). The Ogg Vorbis encoder does not support
this currently.
[mk: this patch was separated from Eric's patch "Refactor and cleanup
of shout Ogg and MP3 audio outputs", I added a description]
Preparing the merge of Eric Wollesen's patch "Refactor and cleanup of
shout Ogg and MP3 audio outputs": we declare one of the struct types
here, to make the merge smoother.