When dmix uses non-interleaved mixing mode the offset and step width
to sum_buffer was calculated by using the dmix channels instead of
the slave channels. This leads to audio distortions due to frame
corruption.
example:
- With below configuratio, Do aplay on both device in parallel for
audio distortion
pcm.dmix_2_channels {
type dmix
ipc_key 5678293
ipc_perm 0660
ipc_gid audio
bindings [0 1]
slave {
pcm "hardware"
channels 2
periods 4
period_time 40000
}
}
pcm.dmix_1_channels {
type dmix
ipc_key 5678293
ipc_perm 0660
ipc_gid audio
bindings [0]
slave {
pcm "hardware"
channels 1
periods 4
period_time 40000
}
}
pcm.hardware {
type hw
card 0
channels 2
rate 48000
format S16_LE
}
Signed-off-by: Vijay Palaniswamy <vijay.palaniswamy@in.bosch.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This mimics snd_pcm_create_iec958_consumer in the kernel.
The rate and wordlength bits will only be modified if they are
set to "not indicated", which is now the default if no status
option is used.
This allows applications to override parameters determined from
the stream or implement channel status bits extensions without
needing to change pcm_iec958 code.
Signed-off-by: Matthias Reichl <hias@horus.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
High bitrate compressed audio data like DTS HD or MAT is usually
packed into 8-channel data. The HDMI specs state this has to be
formatted as a single IEC958 stream, compared to normal multi-
channel PCM data which has to be formatted as parallel IEC958 streams.
As this single-stream formatting mode may break existing setups that
expect non-PCM multichannel data to be formatted as parallel IEC958
streams it needs to be explicitly selected by setting the hdmi_mode
option to true.
The single-stream formatting implementation is prepared to cope with
arbitrary channel counts but only limited testing was done for channel
counts other than 8.
Signed-off-by: Matthias Reichl <hias@horus.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
As Maarten Baert recently reported, the current dmix code applies the
semaphore unnecessarily around mixing streams even when the lockless
mix operation is used on x86. This was rather introduced mistakenly
at the commit 267d7c7281 ("Add support of little-endian on
i386/x86_64 dmix") where the generic dmix code was included on x86,
too.
For achieving the original performance back, this patch changes the
semaphore handling to be checked at run time instead of statically at
compile time.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The recently reported (but a long-standing) bug about the
unconditional semaphore usage in the dmix implies that basically we've
had no problem with the locking in the practical usages over years.
Although the lockless operation has a clear merit, it's a much higher
CPU usage (especially on some uncached pages), and it might lead to a
potential deadlock in theory (which is hard to reproduce at will,
though).
This patch introduces a new configure option "--enable-lockless-dmix"
or "--disable-lockless-dmix" to let user choose the default dmix
operation mode. The usage of the lockless mixing has been already
conditionally enabled via asoundrc and card config
"direct_memory_access", so we just need to set the default value based
on it.
In this patch, the default is set off to the lockless mixing, i.e. the
generic mixing is chosen. It makes more sense from the performance
POV. For any users who still require the lockless operation, it can
be enabled either via configure option or the asoundrc.
The magic number used in the shmem is also changed depending on the
operation mode. It's just for safety, not to conflict both operation
modes with each other.
Reviewed-by: Jaroslav Kysela <perex@perex.cz>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
I took time to understand these functions in the context of the
rest of the code, which would have been a lot quicker with a comment
like this.
Signed-off-by: Mark Hills <mark@xwax.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Match the equivalent funciton for playback. This is on the assumption
that values should be capped at zero, which is what _rewindable()
implements.
Signed-off-by: Mark Hills <mark@xwax.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This looks like a simple mistake dating back to 2003 (commit 7470a5b9)
where code originated from dmix.
Signed-off-by: Mark Hills <mark@xwax.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The previous implementation would mean that stop_threshold behaved
erratically. The intent is to detect that the buffer is too full,
and stop.
In practice, I don't think this was a bug in practice for applications
which don't adjust the stop_threshold. The line above catches those cases.
Signed-off-by: Mark Hills <mark@xwax.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This was the original bug that caused me to start looking at the
ring buffer functions.
In the API this is documented as:
"Delay is distance between current application frame position and
sound frame position. It's positive and less than buffer size in
normal situation, negative on playback underrun and greater than
buffer size on capture overrun. "
Because dsnoop was returning the buffer space available to the hardware
the return value was always quite large, and moved in the wrong
direction.
With this patch, dsnoop now gives results which are comparable to using
the "hw" device directly. My test case was with snd-echo3g (Layla3G).
Signed-off-by: Mark Hills <mark@xwax.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The extplug sets incorrectly the timestamping type to
gettimeofday. Copy the timestamp type from the slave pcm
as other plugins do.
The problem is visible when the
"pcm: dmix: fix sw_params handling of timestamp types in direct plugins"
patch was applied for the direct plugins.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1847508
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
x32 is the x86_64 ABI that uses 32-bit pointers, so requires loading
addresses into edi/esi/ebx rather than rdi/rsi/rbx.
Note that instructions such as movl %eax, (%rdi) do not require
updating, as loading an address into %edi zeroes the high bits, causing
the full %rdi register to hold a valid address.
Signed-off-by: Harald van Dijk <harald@gigawatt.nl>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Feature 'variable periodsize' allows to extend user period size up to
buffer_size/2 independent of slave period. On enlargement of the settings
for period_time.max and period_size.max the setting for openmax
was not updated.
This lead to the effect, that if the slave period itself had openmax
set it was still set on the extended size. Configuration of a period
matching half buffer size was thus rejected.
Example for failure: period size of 384 (half buffer size) is requested
which is rejected and rounded down to 352:
PERIOD_SIZE: [32 352]
BUFFER_SIZE: [64 768]
When correctly applying the openmax setting:
PERIOD_SIZE: [32 384]
BUFFER_SIZE: [64 768]
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
The pthread_mutexattr_t object should be destroyed by calling
pthread_mutexattr_destroy(), otherwise it may cause a potential
memory leak due to the different implement of pthread_mutexattr_init()
Signed-off-by: chunxu.li <chunxuxiao@gmail.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This error code can be used e.g. with echo reference PCM devices
(the SND_USE_CASE_MOD_ECHO_REF UCM token).
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
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>
once draining is done, the pcm enters the SETUP state, which ought to
be valid for snd_pcm_drain()
signed-off-by: Sylvain BERTRAND <sylvain.bertrand@legeek.net>
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>
Minor changes that could help the compiler to produce a
better (smaller/faster) code.
Signed-off-by: Frédéric Recoules <frederic.recoules@orange.fr>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Newer versions of GCC (> 5.0) accept that ebx is declared
in the clobber list even in PIC mode. Meanwhile, even
unlikely, the compiler may use ebx as base address of
one of the memory entry, making subsequent access to
them unreliable ('size', 'dst_step', 'src_step', 'sum_step').
Adding ebx in the clobber solves the problem.
By the way, the entry 'old_ebx' is no longer required.
Signed-off-by: Frédéric Recoules <frederic.recoules@orange.fr>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
- add mm0 in the clobber list if the compiler
is aware of the mmx technology;
- otherwise, add the mmx aliased x87 floating point
registers in the clobbers;
- the configure now checks if the compiler is aware of
the MMX technology.
The compiler assumes none of the mmx or x87 registers are used
by the function. If it chooses to store some data in them, they
will be overwritten by the chunk.
Recall that any mmx instruction invalidate the whole set of
x87 floating point registers.
Note: currently does not impact the binary output.
Signed-off-by: Frédéric Recoules <frederic.recoules@orange.fr>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
- move 'size' and 'old_ebx' in the output section
since they are clobbered;
- add the "memory" clobber since input pointers
are accessed;
- (minor) add the "cc" clobber since flags are
clobbered.
The compiler is missing some dataflow information
about the execution of the assembly chunks.
For instance, it assumes that 'size' remains unchanged
and that no input pointer is accessed.
The compiler optimizer may take advantage of these
assumption and produce a wrong code.
Note: currently produces the same binary output.
Signed-off-by: Frédéric Recoules <frederic.recoules@orange.fr>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
It eases the refactoring of assembly chunk since we can now
add/remove/move entries without worrying about maintaining
the token numbering in the template.
Note: does not impact the binary output.
Signed-off-by: Frédéric Recoules <frederic.recoules@orange.fr>
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>
In pcms using direct plugins (dmix/dsnoop/dshare), the timestamp type could
be different from the terminating hw plugin, then the kernel driver.
Be sure such pcms have plugins using consistently the same timestamp type.
signed-off-by: Sylvain Bertrand <sylvain.bertrand@legeek.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Add a config definition "chmap" to override the channel maps in the same
way as in the hw and null plugins.
Signed-off-by: Jonas Holmberg <jonashg@axis.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Most of PCM API functions have snd_pcm_lock()/unlock() wraps for the
actual calls of ops, and some plugins try to unlock/relock internally
for the given PCM object. This, unfortunately, causes a problem in
some configurations and leads to the unexpected behavior or deadlock.
The main problem is that we call snd_pcm_lock() with the given PCM
object, while calling the ops with pcm->op_arg or pcm->fast_op_arg as
the slave PCM object. Meanwhile the plugin code assumes that the
passed PCM object is already locked, and calls snd_pcm_unlock().
This bug doesn't hit always because in most cases pcm->op_arg and
fast_op_arg are identical with pcm itself. But in some configurations
they have different values, so the problem surfaces.
This patch is an attempt to resolve these inconsistencies. It
replaces most of snd_pcm_lock()/unlock() calls with either pcm->op_arg
or pcm->fast_op_arg, depending on the call pattern, so that the plugin
code can safely run snd_pcm_unlock() to the given PCM object.
Fixes: 54931e5a54 ("pcm: Add thread-safety to PCM API")
Reported-by: Ben Russell <thematrixeatsyou@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
snd_pcm_set_chmap() leaks the memory returned from snd_pcm_get_chmap()
without releasing. Add the missing free() call as well as a slight
code refactoring.
Reported-by: Conrad Jones
BugLink: https://github.com/alsa-project/alsa-lib/pull/11
Fixes: d20e24e5d1 ("chmap: Always succeed setting the map to what it already is")
Signed-off-by: Takashi Iwai <tiwai@suse.de>
allow opening the device and start the audio clock without blocking
any channel
this is required if the audio clock has to be available all the time,
even when application is not streaming audio data
Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
function is allowed to continue until it checks for error variable, as to
not conflict with original implementation flow
for simple functions involving only one line, return error immediately in
case callback is NULL
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
previously errno would be returned even for cases where it may have
not been populated, for example one of the write functions failing,
or writing only partial buffer,
now progress through write operations separately and report errno when
appropriate
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
Reviewed-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
previously, in case of failed write to output file, error is returned
from snd_pcm_writei/read APIs, user could run pcm_drain as fallback and
encounter an assert, since drain would try to write remaining file
buffer to a file
if failed to write to output file in first place, it makes sense to clear
current internal pmc_file file buffer variables
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
Reviewed-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
EPIPE is defined as XRUN which is not entirely correct in this condition
failing to write to a file in pcm_file plugin can not be simply recovered
by a retry as user of the api might be led to believe when receiving EPIPE
use EIO instead to indicate a different kid of error that may not be
recoverable by retry
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
Reviewed-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
snd_pcm_file_add_frames called two times by mistake, introduced in
2a800c0c4f
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
when writing to output file fails, api user is notified and can handle
recovery
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
Reviewed-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
previously playback could be interrupted by snd_pcm_file_add_frames:
assert(file->wbuf_used_bytes < file->wbuf_size_bytes)
in case snd_pcm_file_write_bytes fails to write full amount of bytes
to file, variable wbuf_used_bytes would not be fully decremented by
requested amount of bytes function was called with
for the assert to trigger, multiple write fails need to happen, so
that wbuf_used_bytes overflows wbuf_size_bytes,
this patch will allow application to report error code to api user
who might have an idea how to recover, before assert is triggered,
also reporting error along with the print out message might give user
a better idea of what is going on, where previously reason for
mentioned assert was not immediately clear
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
Reviewed-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
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>