| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
| |
Declare both shout plugins "const", since they will never change, once
initialized at compile time.
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
Don't typedef the structs at all. It is easier to forward-declare
this way.
Don't typedef methods. They are used exactly once, a few lines below.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
[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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
[mk: this patch and its description was separated from Eric's patch
"Refactor and cleanup of shout Ogg and MP3 audio outputs"]
|
|
|
|
|
|
|
|
|
|
|
| |
Begin dividing audioOutput_shout.c: move everything OGG Vorbis related
to audioOutput_shout_ogg.c. The header audioOutput_shout.h has to
keep its dependency on vorbis/vorbisenc.h, because it needs the vorbis
encoder types.
For this patch, we have to export several internal functions with
generic names to the ABI; these will be removed later when the encoder
plugin patches are merged.
|
|
|
|
|
| |
Prepare the split of the shout plugin into multiple sources: move
all important declarations to audioOutput_shout.h.
|
|
|
|
|
|
| |
Remove unused code which is in comments. Remove that comment about
"stolen code", since the plugin has changed much, and it isn't obvious
which parts are derived.
|
| |
|
|
|
|
|
|
| |
If the output device is already open, it may have modified
outAudioFormat; in this case, outAudioFormat is still valid, and does
not need an overwrite.
|
|
|
|
|
|
| |
As long as the device isn't open, both attributes are not used. Since
they will both be initialized in audio_output_open(), we do not need
the initialization in audio_output_init().
|
|
|
|
|
| |
In the plugin's init() function, outAudioFormat is simply a copy of
reqAudioFormat. Use reqAudioFormat instead of outAudioFormat here.
|
|
|
|
|
|
|
| |
Storing pointers to immutable audio_format structs isn't worth it,
because the struct itself isn't much larger than the pointer. Since
the shout plugin requires the user to configure a fixed audio format,
we can simply copy it in myShout_initDriver().
|
|
|
|
|
| |
Eliminate sameInAndOutFormats and check with audio_format_equals()
each time it this information is needed. Another 4 bytes saved.
|
|
|
|
|
| |
Instead of checking convertAudioFormat, we can simply check if
reqAudioFormat is defined. This saves 4 bytes in the struct.
|
|
|
|
| |
We have git..
|
| |
|
|
|
|
|
|
| |
Save one allocation, since the whole audio_format struct is nearly the
same size as the pointer to it. Check audio_format_defined(af)
instead of af!=NULL.
|
|
|
|
|
|
|
| |
free(NULL) isn't explicitly forbidden, but isn't exactly good style.
Check the rare case that the audio buffer isn't initialized yet in
closeAudioDevice(). In this case, we also don't have to call
flushAudioBuffer().
|
|
|
|
|
|
| |
To make openAudioDevice() smaller and more readable, move code to a
static function. Also don't use realloc(), since the old value of the
buffer isn't needed anymore, saving a memcpy().
|
|
|
|
|
|
|
| |
There are too many static variables in audio.c - organize all
properties of the audio buffer in a struct. The current audio format
is also a property of the buffer, since it describes the buffer's
data format.
|
|
|
|
|
|
| |
Passing NULL to this function doesn't make sense, and complicates its
implementation. The one caller which might pass NULL should rather
check this.
|
|
|
|
| |
The function isAudioDeviceOpen() is never used.
|
|
|
|
|
|
|
|
|
| |
audio_format_clear() sets an audio_format struct to an cleared
(undefined) state, which is both faster and smaller than memset(0).
audio_format_defined() checks if the audio_format struct actually has
a defined value (i.e. non-zero). Both can be used to avoid pointers
to audio_format, replacing the "NULL" value with an "undefined"
audio_format.
|
|
|
|
| |
Remove one comparison by changing branch order.
|
|
|
|
|
|
|
|
|
| |
Since the caller chain doesn't care about the return value (except for
COMMAND_RETURN_KILL, COMMAND_RETURN_CLOSE), just return 0 if there is
nothing special. This saves one local variable initialization, and
one access to it.
Also remove one unreachable "return 1" from client_read().
|
|
|
|
|
|
|
| |
Don't close the client within client_process_line(), return
COMMAND_RETURN_CLOSE instead. This is the signal for the caller chain
to actually close it. This makes dealing with the client pointer a
lot safer, since the caller always knows whether it is still valid.
|
|
|
|
| |
It's easier to reuse the variable if it has a more generic name.
|
|
|
|
| |
Don't update client data if it is going to be closed anyway.
|
|
|
|
|
| |
Rename it to audio_format_equals() and return "true" if they are
equal.
|
|
|
|
|
|
|
|
|
| |
The "!src" check in copyAudioFormat() used to hide bugs - one should
never pass NULL to it. There is one caller which might pass NULL, add
a check in this caller.
Instead of doing mempcy(), we can simply assign the structures, which
looks more natural.
|
|
|
|
| |
Getting rid of CamcelCase, again.
|
|
|
|
|
| |
Similar to decoder_control.c, output_control.c will provide functions
for controlling the output thread (which will be implemented later).
|
|
|
|
| |
No CamelCase. Also don't declare typedefs for the methods.
|
|
|
|
| |
This function is declared, but is neither used nor implemented.
|
|
|
|
|
| |
The audio_format argument to timer_new() should be constant, because
it is not modified. The same is true for ShoutData.audioFormat.
|
|
|
|
|
| |
Otherwise we'd be writing to whatever directory that mpd is
running in.
|
|
|
|
|
|
|
|
|
|
|
|
| |
The way we used non-blocking mode was HORRIBLE.
It was non-blocking to ALSA, but we end up blocking in a busy
loop that does absolutely NOTHING but retry. We don't check
for playback cancellation (like we do in decoders) or anything.
This is seriously broken and I can imagine it affects people on
fast CPUs more because we do asynchronous output buffering and
our ALSA device will always have data ready.
|
|
|
|
|
| |
Lets not use deprecated functions. It's apparently
possible to not care about the sw_params stuff at all!
|
|
|
|
|
|
|
|
|
| |
This is safer than the patch in
http://www.musicpd.org/mantis/view.php?id=1542
with multiple audio outputs enabled.
Sadly, I only noticed that patch/problem when I googled for
"snd_config_update_free_global"
|
| |
|
| |
|
|
|
|
|
| |
We never use it for anything anyways as we release the device
entirely on pause.
|
|
|
|
| |
That's the name of this project.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Apparently snd_pcm_hw_params_can_resume() can return false even
though my hardware does in fact support resuming. So stop
carrying that value in the canResume flag and just try to resume
when we're in the suspended state; falling back to
snd_pcm_prepare only if resuming fails. libao does something
similar on resume, too.
While we're at it, use the E() macro which will enable us to
have better error reporting.
[mk: remove the E() macro stuff]
|
|
|
|
|
| |
Due to a minor typo, the string set had duplicate values, because
strset_add() didn't check the base slot properly.
|
|
|
|
|
|
|
| |
With a large music database, the linear string collection in
tagTracker.c becomes very slow. We implemented that in a
quick'n'dirty fashion when we removed tree.c, and now we rewrite it
using the fast hashed string set.
|