Shuffle the code to avoid special conditions using the plugin type
in the generic plugin code. The rate plugin has the own
may_wait_for_avail_min callback implementation now.
Fixes: d21e0e01 ("pcm: plugin - fix avail_min calculation on rate plugin")
Fixes: https://github.com/alsa-project/alsa-lib/pull/218
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
commit 88e4ae27, ff1f669d introduced a dynamic recalculation of the slave's
avail_min value.
The calculated avail_min setting did not take into account, that the avail_min value
depends on the used sampling rate and must be adapted accordingly
if the slave is using a different sampling rate.
That leads to too large/too small calculated avail_min settings and inaccurate
period wake-up events if a rate converter plugin is used.
This patch is adapting the avail_min calculation to consider a different
sampling rate between actual pcm and it's slave.
Fixes: https://github.com/alsa-project/alsa-lib/pull/218
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
In the case that:
* the buffer size is not an integer multiple of the period size, and
* drain must flush a partial period located before the end of the buffer
but without a full period available, where
* these conditions may pertain to the source or slave pcm buffer, and
* because rate conversion is always done on a full period,
it is necessary to check that both a full source period is available
before source pcm buffer wrap and a full slave period is available
before slave pcm buffer wrap in order to use the simple, single-commit
implementation in snd_pcm_rate_commit_area().
The alternative fix would be to change snd_pcm_rate_write_areas1() to
take size and slave_size parameters. This would be more disruptive to
the code base, tricky to get right, and is unnecessary given that
snd_pcm_mmap_commit() only commits the partial period of actually valid
converted samples.
Fixes: 3047f8fa5a ("Fix possible problems of playback drain with rate plugin")
Signed-off-by: Alan Young <consult.awy@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This patch extends the PCM rate plugin for allowing its converter
plugin to deal with multiple formats. Currently, the converter plugin
is allowed to take different formats only when convert callback is
defined. And for this way (so far only the standard linear rate
plugin does), all linear formats have to be handled, and it's
cumbersome.
OTOH, most other rate plugins are implemented with convert_s16
callback, which accepts only S16 format. This is often not ideal
because many converter engines can handle 32bit formats. Also, the
target format is often 32bit format, hence this would require
additional conversion even if the converter engine can output 32bit
natively.
In this patch, for addressing the problems above, the rate plugin API
is extended in the following way:
- The new get_supported_formats callback is added; this stores the bit
masks of the supported input and output formats, as well as the
behavior flags. Currently only linear formats are allowed.
- When the plugin accepts only the interleaved stream, set
SND_PCM_RATE_FLAG_INTERLEAVED flag bit. Otherwise the code has to
handle snd_pcm_channel_area at each call.
- When both input and output formats have to be identical, pass
SND_PCM_RATE_FLAG_SYNC_FORMATS flag bit.
- When the converter wants to process different formats, use convert
callback instead of convert_s16. You can put both in the ops for
compatibility, too.
The input and output formats are found in the info argument of init
callback.
- Now the PCM rate plugin core will skip the temporary buffer
allocation and conversions for pre- and post-process if not needed
(i.e. matching with the requested input or output format).
The rate plugin API version is bumped to 0x010003.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Introduce common helpers to allocate and release the temporary buffers
and the associated snd_pcm_channel. Now two allocated objects are
used instead of one malloc to be split.
Also, change the snd_pcm_channel set up to be in interleaved mode.
This will be necessary in the following change in the rate plugin.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
In commit b906db19ef, the snd_dlopen()
implements the automatic lookup to the ALSA_PLUGIN_DIR directory.
It is not necessary to add the absolute paths in callers now.
The plugin names are also searched in ld.so.conf paths as the fallback now,
but it should not be a big problem.
BugLink: https://github.com/alsa-project/alsa-lib/issues/34
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
The recent gcc warning indicates the uninitialized variable commit_err:
pcm_rate.c:1104:6: warning: ‘commit_err’ may be used uninitialized in this function [-Wmaybe-uninitialized]
if (commit_err < 0)
^
Add a proper initialization to commit_err.
Fixes: 29041c5220 ("fix infinite draining of the rate plugin in SND_PCM_NONBLOCK mode")
Signed-off-by: Takashi Iwai <tiwai@suse.de>
We've got a gcc warning:
pcm_rate.c: In function ‘snd_pcm_rate_drain’:
pcm_rate.c:1090:19: warning: suggest parentheses around comparison in operand of ‘&’ [-Wparentheses]
if (pcm->mode & SND_PCM_NONBLOCK != 0) {
^
Drop the zero comparison for fixing the warning and for simplicity.
Fixes: 29041c5220 ("fix infinite draining of the rate plugin in SND_PCM_NONBLOCK mode")
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The draining function of the rate plugin does not handle properly the
SND_PCM_NONBLOCK case. It can write data to the slave plugin each time the
function is called, but does not update its internal state in order to
reach a stopping condition. Use a last_commit_ptr workaround to reach such
condition.
Signed-off-by: Sylvain BERTRAND <sylvain.bertrand@legeek.net>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
The pointer operand to the binary `+` operator must be to a complete
object type.
Signed-off-by: Michael Forney <mforney@mforney.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Without these changes a negative error code returned by
snd_pcm_avail_update() will be not handled correctly.
With this patch the returned error code of snd_pcm_avail_update() will be
returned by snd_pcm_rate_avail_update().
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
If a rate plugin uses a node (compound) instead of a plain string for
its "converter", and that compound is not a simple string array, then
the compound will be passed as an additional parameter to the new plugin
open() function (SND_PCM_RATE_PLUGIN_CONF_ENTRY(XXX)). The previous
open() function (SND_PCM_RATE_PLUGIN_ENTRY(XXX)) will be called if the
CONF version is not found. It is up to the plugin to determine whether
the presence of the conf parameter is mandatory.
Signed-off-by: Alan Young <consult.awy@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
For long time test case, the slave_hw_ptr will exceed the boundary
and wraparound the slave_hw_ptr. This slave boundary wraparound will
cause the rate->hw_ptr to wraparound irrespective of the
rate->boundary availability and due to that the available size goes
wrong.
Hence, to get the correct available size,
- Its necessary to increment the rate->hw_ptr upto the rate->boundary
and then wraparound the rate->hw_ptr.
- While handling fraction part of slave period, rounded value will be
introduced by input_frames(). To eliminate rounding issue on
rate->hw_ptr, subtract last rounded value from rate->hw_ptr and add
new rounded value of present slave_hw_ptr fraction part to
rate->hw_ptr.
Signed-off-by: mahendran.k <mahendran.kuppusamy@in.bosch.com>
Signed-off-by: Mounesh Sutar <mounesh_sutar@mentor.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
snd_pcm_rate_status() gets the underlying status from the slave PCM.
This may contain a delay value that includes elements such as codec and
other transfer delays. Use this as the base for the returned delay
value, adjusted for any frames buffered locally (within the rate
plugin).
Also update snd_pcm_rate_delay() similarly.
[fixed some comments by tiwai]
Signed-off-by: Alan Young <consult.awy@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
We've had a few home brew atomic operations in a couple of places in
the PCM code. This was for supporting the concurrent accesses, but in
practice, it couldn't cover the race properly by itself alone.
Since we have a wider concurrency protection via mutex now, we can get
rid of these atomic codes, which worsens the portability
significantly.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Traditionally, many of ALSA library functions are supposed to be
thread-unsafe, and applications are required to take care of thread
safety by themselves. However, people never be careful enough, and
almost all applications fail in this regard.
This patch is an attempt to harden the thread safety in exported PCM
functions in a simplistic way: just wrap some of exported functions
with the pthread mutex of each PCM object. Not all API functions are
wrapped by the mutex since it doesn't make sense. Instead, the
patchset covers only the functions that may be likely called
concurrently. The supposedly thread-safe API functions are marked in
the document.
For achieving the feature, two new fields are added snd_pcm_t when the
option is enabled: thread_safe and lock. The former indicates that
the plugin is thread-safe that doesn't need this workaround and the
latter is the pthread mutex. Currently only hw plugin have
thread_safe=1. So, the most of real-time sensitive apps won't be
influenced by this patchset.
Although the patch covers most of PCM ops, a few snd_pcm_fast_ops are
left without the extra mutex locking: namely, the ones that may have
blocking behavior, i.e. resume, drain, readi, writei, readn and
writen. These are supposed to handle own locking in the callbacks.
Also, if anyone wants to disable this new thread-safe API feature, it
can be still turned off via --disable-thread-safety configure option.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
If it is, then it means most likely the driver problem, so we should
return error immediately instead.
Signed-off-by: Alexander E. Patrakov <patrakov@gmail.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Such negative returns are possible during an underrun if xrun detection
is disabled.
So, don't store the result in an unsigned variable (where it will
overflow), and postpone the trigger in such case, too.
Signed-off-by: Alexander E. Patrakov <patrakov@gmail.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Now all PCM plugins do support the proper timestamp type or pass it
over slaves. The internal monotonic flag is dropped and replaced with
tstamp_type in all places.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
For long time test case, the hw_ptr will exceed the boundary, then cause
the avail size wrong.
Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit does not fix nonsense values returned by the rewind and
forward callbacks. E.g., with period_size = 1024 and buffer_size = 4096,
an attempt to rewind 1024 samples from the nearly-full buffer returns
4090.
Due to these nonsense values, the current rate plugin should be treated
as non-rewindable. That's why the new callbacks return 0.
Signed-off-by: Alexander E. Patrakov <patrakov@gmail.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
snd_pcm_rewind is documented to return <0 on failure and >=0 on
success.
Signed-off-by: Andrew Eikum <aeikum@codeweavers.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
snd_pcm_write_areas() tries to wait until avail >= avail_min condition
is satisfied. This doesn't work always well when a rate plugin is in
the play.
When a partial data with a smaller size than a period is written, the
rate plugin doesn't transfer the data immediately to the slave PCM,
but kept in an internal buffer and it changes only the hwptr of the
plugin. Thus, the condition "avail < avail_min" is triggered for a
wait check although the underlying slave PCM has enough room. This
results in a call of snd_pcm_wait() which returns immediately after
poll() call, and the snd_pcm_write_areas() loop continues. As a
consequence, it falls into a CPU hog.
This patch fixes that busy loop by introducing a new fast_ops to check
the availability for wait of avail_min. Then a plugin can ask the
slave PCM whether the wait is required (or possible).
A few plugins like multi plugin need a special handling. Otherwise a
generic plugin function can be used.
Reported-by: Trent Piepho <tpiepho@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Added new channel-mapping API functions.
Not all plugins are covered, especially the route, multi and external
plugins don't work yet.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Something that is allocated using calloc is not freed on one
or more error paths.
Signed-off-by: Julia Lawall <julia@diku.dk>
Signed-off-by: Suman Saha <sumsaha@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
- changed logic to get/put blocks
- added mutex locking of the symbol list
- added reference counting (do not free used dl handles)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Extend the PCM-rate plugin protocol to allow the host to query the
supported sample rates. The protocol version is bumped to 0x010002,
and the version number negotiaion is slightly changed.
Now the plugin is supposed to fill the version it supports in return.
The old versioned plugins are still supported, but they may spew
version-mismatch warning prints.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Use "const char *const []" as type for string arrays, or convert to
"const char [][x]" when it makes sense.
Signed-off-by: Diego E. 'Flameeyes' Pettenò <flameeyes@gmail.com>
This ensures they are emitted in .data.rel.ro rather than .data.rel,
which should make a nice difference when using prelink.
Signed-off-by: Diego E. 'Flameeyes' Pettenò <flameeyes@gmail.com>