Commit graph

1464 commits

Author SHA1 Message Date
Adam Miartus
845243bcc2 pcm: dshare: allow missing bindings
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>
2019-07-24 15:18:05 +02:00
Adam Miartus
3bf780dcc3 pcm: return -ENOSYS when ops or fast_ops callback is NULL
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>
2019-07-24 15:16:32 +02:00
Adam Miartus
d7ee2a9a30 pcm_file: improve error checking in write_wav_header function
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>
2019-07-05 17:00:15 +02:00
Adam Miartus
de1a9b2e81 pcm_file: in case of failed write clear file buffer variables
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>
2019-07-03 14:23:03 +02:00
Adam Miartus
61b0f8f3f2 pcm_file: use EIO instead of EPIPE when failing to write output file
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>
2019-07-03 14:22:43 +02:00
Adam Miartus
053b430980 pcm_file: return errno in case of a failed write operation
allows correct error code propagation for snd_pcm_file_write_bytes caller

Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-06-24 14:24:04 +02:00
Adam Miartus
7b1af71173 pcm_file: remove double line
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>
2019-06-24 14:12:57 +02:00
Adam Miartus
2a800c0c4f pcm_file: report write output file error to api user
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>
2019-06-15 10:34:59 +02:00
Adam Miartus
6ecd330fb8 pcm_file: do not disrupt playback on output file write fail
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>
2019-06-15 10:34:53 +02:00
Michael Forney
03b2f3d056 pcm: rate: Avoid pointer arithmetic on void *
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>
2019-06-12 08:53:17 +02:00
Michael Forney
6882ad4a74 pcm: direct: Remove unused empty struct
Signed-off-by: Michael Forney <mforney@mforney.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-06-12 08:53:03 +02:00
Michael Forney
630844e36c pcm: Make sure parameter qualifiers match between declaration and definition
Signed-off-by: Michael Forney <mforney@mforney.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-06-12 08:52:49 +02:00
Michael Forney
80376889af pcm: hw: Don't return in a void function
A return statement with an expression in a function returning void is
a constraint violation.

Signed-off-by: Michael Forney <mforney@mforney.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-06-12 08:52:36 +02:00
Michael Forney
0baf7b377c Use __func__ instead of __FUNCTION__
They are equivalent, but __func__ is in C99. __FUNCTION__ exists only
for backwards compatibility with old gcc versions.

Signed-off-by: Michael Forney <mforney@mforney.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-06-12 08:52:07 +02:00
Jaroslav Kysela
ac6df1106c pcm_file: another locking fix (coverity)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2019-05-27 20:10:32 +02:00
Jaroslav Kysela
022c790aab pcm_file: coverity fixes (including double locking)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2019-05-27 14:04:52 +02:00
Jaroslav Kysela
3ae743efea pcm_hw: close file descriptor in the error path in snd_pcm_hw_open() (coverity)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2019-05-24 21:25:50 +02:00
Jaroslav Kysela
22ade9b8c1 pcm_file: call pclose() correctly for popen() (coverity)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2019-05-24 21:25:50 +02:00
Jaroslav Kysela
d5a1cf35b7 pcm: fix memory leak in _snd_pcm_parse_config_chmaps() (coverity)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2019-05-24 21:25:50 +02:00
Adam Miartus
fe7ff721a9 pcm: file: add infile read support for mmap mode
mmap_begin callback is used to copy data from input file to mmaped
buffer

guard for corner use of api (multiple mmap_begin calls by user) is
introduced to check if next continuous buffer was already overwritten

buffer is overwritten with input file data only in case of stream capture

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>
2019-05-24 11:16:05 +02:00
Adam Miartus
e520f45480 pcm: add mmap_begin callback to snd_pcm_fast_ops_t api
main motivation for adding the callback is to use it to enable operation
on mmaped buffer before user access for pcm_file plugin

support for MMAP read access with masking by data from input file is not
implemented for pcm_file plugin, by adding this callback implementing
such feature can be done by rewriting next continuous portion of buffer
on each mmap_begin call

plugins like softvol use pcm_plugin interface and overwrite the buffer by
looping around it in avail_update callback, this patch hopes to simplify
the task by adding new api callback, removing the need for rewriting
pcm_file (to use pcm_plugin callbacks) and careful checking when looping
around whole mmaped buffer

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>
2019-05-24 11:06:44 +02:00
Adam Miartus
33c7ea0865 pcm: file: add missing unlock on early return
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-05-23 11:55:47 +02:00
Adam Miartus
349b42f547 pcm: file: use snd_pcm_file_areas_read_infile for readi
use previously introduced helper function, this commit unifies behavior
of readi and readn

corner case behavior of readi is changed by this commit, previously,
in case 0 bytes were red from file (EOF), frames = 0 was returned,
signaling api user as if no data was red from slave, after the patch,
amount of frames red from slave with data red from slave stored in buffer
is returned when EOF is reached

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>
2019-05-22 16:20:26 +02:00
Adam Miartus
5f2e5af61b pcm: file: add support for infile reading in non interleaved mode
add helper function to copy input file data to buffer mapped by areas,
in case of an error, do not fill the areas, allowing device read buffer
to be provided to api caller

previously unused rbuf variable is reused for this purpose

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>
2019-05-22 16:19:31 +02:00
Vanitha Channaiah
3ab7980047 pcm: dsnoop: Added "hw_ptr_alignment" option in configuration for slave pointer alignment
This change adapt the fix commit 6b058fda9d
("pcm: dmix: Add option to allow alignment of slave pointers")
for dsnoop plugin

Issue is that snd_pcm_wait() goes back to waiting because the hw_ptr
is not period aligned. Therefore snd_pcm_wait() will block for a longer
time as required.

With these rcar driver changes the exact position of the dma is returned.
During snd_pcm_start they read hw_ptr as reference, and this hw_ptr
is now not period aligned, and is a little ahead over the period while it
is read. Therefore when the avail is calculated during snd_pcm_wait(),
it is missing the avail_min by a few frames.

An additional option hw_ptr_alignment is provided to dsnoop configuration,
to allow the user to configure the slave application and hw pointer
alignment at startup

Signed-off-by: Vanitha Channaiah <vanitha.channaiah@in.bosch.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-05-15 10:33:02 +02:00
Vanitha Channaiah
7265e603bf pcm: dshare: Added "hw_ptr_alignment" option in configuration for alignment of slave pointers
This change adapt the fix commit 6b058fda9d
("pcm: dmix: Add option to allow alignment of slave pointers")
for dshare plugin

Issue is that snd_pcm_wait() goes back to waiting because the hw_ptr
is not period aligned. Therefore snd_pcm_wait() will block for a longer
time as required.

With these rcar driver changes the exact position of the dma is returned.
During snd_pcm_start they read hw_ptr as reference, and this hw_ptr
is now not period aligned, and is a little ahead over the period while it
is read. Therefore when the avail is calculated during snd_pcm_wait(),
it is missing the avail_min by a few frames.

An additional option hw_ptr_alignment is provided to dshare configuration,
to allow the user to configure the slave application and hw pointer
alignment at startup

Signed-off-by: Vanitha Channaiah <vanitha.channaiah@in.bosch.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-05-15 10:32:32 +02:00
Vanitha Channaiah
63ba5243ab pcm: direct: Add generic hw_ptr_alignment function for dmix, dshare and dsnoop
Move the code snd_pcm_direct_reset_slave_ptr() from pcm_dmix.c
to pcm_direct.c and its header so that the helper function can be
re-used by other direct-pcm plugins.
There is no change in the behavior or the functionality.

Signed-off-by: Vanitha Channaiah <vanitha.channaiah@in.bosch.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-05-15 10:31:20 +02:00
Jaroslav Kysela
5366bdb4fb add support for GCC's LTO 2019-04-09 12:44:14 +02:00
Jaroslav Kysela
0bfad420ef pcm: multi plugin: reset hw/appl pointers in prepare/reset functions
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2019-04-09 10:34:42 +02:00
Jaroslav Kysela
369df32257 pcm: multi plugin: detach the hw_ptr and appl_ptr from master_slave
Unfortunately, the master_slave buffer pointers are not always in sync with
the presented avail value and the higher layers (like write_areas) got
confused. Create own hw_ptr and appl_ptr.

This commit also tries to fix the hwsync and delay implementation (iterate
through all slaves).

The multi plugin was designed only for hardware which runs really in sync.
Anyway, users are trying to use this plugin for other purposes.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2019-04-09 10:27:36 +02:00
Jaroslav Kysela
c7fc3fdbe2 pcm: fix wait condition in snd_pcm_write_areas() to avoid return zero
The hw_ptr might be updated during the snd_pcm_may_wait_for_avail_min() call,
so even if it returns zero (OK), the avail must be updated again.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2019-04-09 10:27:36 +02:00
Jaroslav Kysela
4694a6643d pcm: multi plugin - fix wait_for_avail_min
All slaves should be asked to wait otherwise the write loop might
be interrupted and zero frames might be returned.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2019-04-09 10:27:36 +02:00
Timo Wischer
0d92f2d39a pcm: null: Do not allow a period size of 0
Some applications do not expect that get_period_size_min() could
return 0. Therefore these applications cannot use the null plugin without
this patch.
Due to there is no use case for having a period size of 0 this patch
disallows a period size of 0 when using the null plugin.

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-04-08 14:27:29 +02:00
Jaroslav Kysela
f9056d013c pcm: rate plugin - fix signess in snd_pcm_rate_avail_update() comparison
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2019-03-25 16:56:34 +01:00
Jaroslav Kysela
1755df1d9e add snd_strlcpy() and use it everywhere
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2019-03-25 16:46:05 +01:00
Chih-Wei Huang
e6f8998258 pcm: add the missing <strings.h> include
To define the prototype of ffs. See 'man ffs'.

Signed-off-by: Chih-Wei Huang <cwhuang@linux.org.tw>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2019-03-15 13:16:15 +01:00
Brendan Shanks
7cea8c1562 pcm: dshare: Fix overflow when slave_hw_ptr rolls over boundary
In snd_pcm_dshare_sync_area() when 'slave_hw_ptr' rolls over
'slave_boundary', the wrong variable is checked ('dshare->slave_hw_ptr' vs
the local 'slave_hw_ptr'). In some cases, this results in 'slave_hw_ptr'
not rolling over correctly. 'slave_size' and 'size' are then much too
large, and the for loop blocks for several minutes copying samples.

This was likely only triggered on 32-bit systems, since the PCM boundary
is computed based on LONG_MAX and is much larger on 64-bit systems.

This same change was made to pcm_dmix in commit
6c7f60f7a9 ("Fix boundary overlap”) from
June 2005.

Signed-off-by: Brendan Shanks <brendan.shanks@teradek.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-02-12 14:37:44 +01:00
Takashi Iwai
9c1439a76c pcm: Preserve period_event in snd_pcm_hw_sw_params() call
snd_pcm_hw_sw_params() in pcm_hw.c tries to abuse the reserved bits
for passing period_Event flag.  In this hackish way, we clear the
reserved bits at beginning, and restore before returning.  However,
the code paths that return earlier don't restore the value, hence when
user calls this function twice, it may pass an unexpected value.

This patch fixes the failure, restoring the value always before
returning from the function.

Reported-by: Jamey Sharp <jamey@minilop.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-01-09 12:02:56 +01:00
Takashi Iwai
d7ba06afce pcm: ioplug: Fix the regression of pulse plugin drain
The recent change to support the drain via polling caused a regression
for pulse plugin; with speaker-test -c2 -twav with pulse, it leads to
either no sounds or stall.

The only sensible behavior change in the commit wrt pulse plugin is
that now it starts the stream before calling drain callback.  This
supposed to be correct, but it seems hitting a pulse plugin bug.

The start before drain callback is only a matter of consistency, and
since this doesn't work for the single existing plugin using drain
callback, we don't need to stick with this behavior.

For addressing the regression, we check the presence of the drain
callback and start the stream only when it doesn't exist, i.e. only in
drain-via-poll mode.

Fixes: ce2095c41f ("pcm: ioplug: Implement proper drain behavior")
Reported-by: Diego Viola <diego.viola@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-12-19 14:23:38 +01:00
Timo Wischer
ee64b4b83a pcm: extplug: Keep format and channels the same if requested
Without this patch it is not possible to link the channel and format
parameter if snd_pcm_extplug_set_param_*() or
snd_pcm_extplug_set_slave_param_*() is called. Therefore the client and
slave parameter can differ. So the extplug has to implement conversion.

To avoid this the new snd_pcm_extplug_set_param_link() function can be
called.
As a reproduction sceanrio the following extplug source code can be used:

===
static snd_pcm_sframes_t my_transfer(snd_pcm_extplug_t *e,
	const snd_pcm_channel_area_t *da, snd_pcm_uframes_t dof,
	const snd_pcm_channel_area_t *sa, snd_pcm_uframes_t sof,
	snd_pcm_uframes_t s) {
	return s;
}
static const snd_pcm_extplug_callback_t my_own_callback = {
	.transfer = my_transfer
};
SND_PCM_PLUGIN_DEFINE_FUNC(my_plug) {
	snd_config_iterator_t i, next;
	snd_config_t *slave = NULL;
	snd_pcm_extplug_t *myplug;
	snd_config_for_each(i, next, conf) {
		snd_config_t *n = snd_config_iterator_entry(i);
		const char *id;
		if (snd_config_get_id(n, &id) < 0)
			continue;
		if (strcmp(id, "comment") == 0 || strcmp(id, "type") == 0)
			continue;
		if (strcmp(id, "slave") == 0) {
			slave = n;
			continue;
		}
		return -EINVAL;
	}
	myplug = calloc(1, sizeof(*myplug));
	myplug->version = SND_PCM_EXTPLUG_VERSION;
	myplug->callback = &my_own_callback;
	snd_pcm_extplug_create(myplug, name, root, slave, stream, mode);

	snd_pcm_extplug_set_param_minmax(myplug,
		SND_PCM_EXTPLUG_HW_CHANNELS, 1, 16);
//	snd_pcm_extplug_set_param_link(myplug, SND_PCM_EXTPLUG_HW_CHANNELS, 1);

	*pcmp = myplug->pcm;
	return 0;
}
SND_PCM_PLUGIN_SYMBOL(my_plug);
===

To use this plugin the following ALSA configuration is required:

pcm.myplug {
    type my_plug
    slave.pcm hw:Dummy
}

With this configuration without this patch
snd_pcm_hw_params_get_channels_max() will always return 16 channels
independent of the supported channels of the dummy device. Due to that for
example the start up of JACK would fail:

$ modprobe snd_dummy
$ jackd -d alsa -P myplug
ALSA: cannot set channel count to 16 for playback
ALSA: cannot configure playback channel

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-12-10 11:53:41 +01:00
Kirill Marinushkin
d3dfef24bf pcm: dshare: Fix segfault when not binding channel 0
Configuration to reproduce:

~~~~
pcm.share_right {
  type dshare
  ipc_key 73
  ipc_perm 0666
  slave {
    pcm "hw:0,0"
  }
  bindings {
    # the seagfault happens when we don't bind channel 0
    1 1
  }
}
~~~~

Execute to reproduce:

~~~~
$ aplay -D plug:share_right test.wav
Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
Segmentation fault
~~~~

For channels whithout binding, values are set to UINT_MAX in function
`snd_pcm_direct_parse_bindings()`:

~~~~
	for (chn = 0; chn < count; chn++)
		bindings[chn] = UINT_MAX;		/* don't route */
~~~~

But, these values are not checked when playing, which causes the segfault.

This commit fixes the issue.

Signed-off-by: Kirill Marinushkin <kmarinushkin@birdec.tech>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-11-21 11:01:21 +01:00
Laxmi Devi
6b058fda9d pcm: dmix: Add option to allow alignment of slave pointers
These changes are required due to the kernel
commit 07b7acb51d283d8469696c906b91f1882696a4d4
("ASoC: rsnd: update pointer more accurate")

Issue is that snd_pcm_wait() goes back to waiting because the hw_ptr
is not period aligned. Therefore snd_pcm_wait() will block for a longer
time as required.

With these rcar driver changes the exact position of the dma is returned.
During snd_pcm_start they read hw_ptr as reference, and this hw_ptr
is now not period aligned, and is a little ahead over the period while it
is read. Therefore when the avail is calculated during snd_pcm_wait(),
it is missing the avail_min by a few frames.

An additional option hw_ptr_alignment is provided to dmix configuration,
to allow the user to configure the slave application and hw pointer
alignment at startup

[ Slight indentation and parentheses removals by tiwai ]

Signed-off-by: Laxmi Devi <Laxmi.Devi@in.bosch.com>
Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-11-13 15:18:40 +01:00
Timo Wischer
b420056604 pcm: interval: Interpret (x x+1] correctly and return x+1
Without this change an interval of (x x+1] will be interpreted as an
empty interval but the right value would be x+1.
This leads to a failing snd_pcm_hw_params() call which returns -EINVAL.

An example issue log is given in the following:
snd_pcm_hw_params failed with err -22 (Invalid argument)
ACCESS: MMAP_NONINTERLEAVED
FORMAT: S16_LE
SUBFORMAT: STD
SAMPLE_BITS: 16
FRAME_BITS: 16
CHANNELS: 1
RATE: 16000
PERIOD_TIME: (15999 16000]
PERIOD_SIZE: (255 256]
PERIOD_BYTES: (510 512]
PERIODS: [2 3)
BUFFER_TIME: 32000
BUFFER_SIZE: 512
BUFFER_BYTES: 1024

In case of (x x+1) we have to interpret it anyway as a single value of x to
compensate rounding issues.
For example the period size will result in an interval of (352 353) when
the period time is 16ms and the sample rate 22050 Hz
(16ms * 22,05 kHz = 352,8 frames). But 352 has to be chosen to allow a
buffer size of 705 (32ms * 22,05 kHz = 705,6 frames) which has to be >= 2x
period size to avoid Xruns. The buffer size will not end up with an
interval of (705 706) simular to the period size because
snd_pcm_rate_hw_refine_cchange() calls snd_interval_floor() for the buffer
size. Therefore this value will be interpreted as an integer interval
instead of a real interval further on.

This issue seems to exist since the change of 9bb985c38 ("pcm:
snd_interval_refine_first/last: exclude value only if also excluded
before")

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2018-10-24 12:07:33 +02:00
Rob Duncan
1714332719 pcm: ioplug: Transfer all available data
The snd_pcm_mmap_begin() call returns the amount of contiguous data,
which is less than the total available if it wraps around the buffer
boundary.

If we don't handle this split we leave stale data in the buffer that
should have been overwritten, as well as unread data in the io_plugin
that gets transferred on a subsequent call at the wrong offset.

Signed-off-by: Rob Duncan <rduncan@teslamotors.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-07-17 17:52:52 +02:00
Timo Wischer
2c04ea1f29 pcm: rate: Add error check for snd_pcm_avail_update()
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>
2018-07-04 15:41:21 +02:00
Timo Wischer
2972f2f966 pcm: ioplug: Provide avail helper function for plugins
This function can be called without calling snd_pcm_avail_update().

The call to snd_pcm_avail_update() can take some time.
Therefore some developers would not like to call it from a real-time
context (e.g. from JACK client context).

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-07-03 16:36:34 +02:00
Timo Wischer
9bb985c382 pcm: snd_interval_refine_first/last: exclude value only if also excluded before
Without this commit the following intervals [x y), (x y) were be
replaced to (y-1 y) by snd_interval_refine_last(). This was also done if
y-1 is part of the previous interval.
With this changes it will be replaced with [y-1 y) in case of y-1 is
part of the previous interval. A similar behavior will be used for
snd_interval_refine_first().

This solves the issue reported here:
https://bugzilla.opensuse.org/show_bug.cgi?id=1033179
and work arounded with commit
e736715 ("pcm: dmix: Disable var_periodsize as default").

I am able to reproduce the issue with a simplified aplay use case using
the following configuration:
pcm_slave.adr3_tdm_8ch {
    pcm {
        type hw
        card "Loopback"
        device 0
    }
    rate 48000
    period_size 128
    buffer_size 1024
    channels 2
}

pcm.dshare_Playback_3 {
    type dmix
    ipc_key 600
    ipc_perm 0660
    ipc_gid audio
    var_periodsize true
    slave adr3_tdm_8ch
}

pcm.AdevAcousticoutSpeech {
    type rate
    slave.pcm dshare_Playback_3
    slave.rate 48000
}

$ modprobe snd_aloop
$ aplay -v --period-size=352 -c2 -fS16_LE -r22500 -DAdevAcousticoutSpeech /dev/urandom
...
Rule 9 (0xffff91d1f230): PERIODS=(0 2) -> NONE BUFFER_SIZE=480 PERIOD_SIZE=[240 240]
refine_soft 'AdevAcousticoutSpeech' (end--22)
...
aplay: ../../alsa-utils-1.1.5/aplay/aplay.c:1390: set_params: Assertion `err >= 0' failed.
Aborted by signal Aborted...

The following stack trace shows where the -EINVAL will be thrown:
__snd_pcm_hw_params_set_period_size_near()
snd1_pcm_hw_param_set_near()
snd1_pcm_hw_param_set_last()
snd1_pcm_hw_refine_slave()
snd1_pcm_hw_refine_soft()
snd_pcm_hw_rule_div()
snd1_interval_refine()

This issue exists due to PERIODS does not include 2
Rule 9 (0xffff91d1f230): PERIODS=(0 9) -> (0 2) BUFFER_SIZE=[120 480]
PERIOD_SIZE=(240 241)
because of an invalid integer inverval of PERIOD_SIZE of (240 241).
This interval is set by snd_interval_refine_last().

Signed-off-by: Timo Wischer <twischer@de.adit-jv.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-07-03 12:47:32 +02:00
Takashi Iwai
9fc248925b pcm: Define refine mask bits explicitly (and fix missing DSD support)
Instead of the expanded bit numbers like 0x81ffffff, list up the all
supported PCM bits explicitly for refine_masks[] in pcm_params.c.
This makes easier to update any additional formats or other
parameters, and easier to spot out missing ones.

Actually the GSM and DSD formats were missing; with this commit, they
are supported properly now.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-06-28 07:59:46 +02:00
Takashi Iwai
6f134a822a pcm: dmix: Fix hwptr updates at status call
In the commit 38a2d2eda8 ("pcm: dmix: Do not discard slave reported
delay in status result"), the PCM dmix hwptr update code was rewritten
to follow the slave PCM hwptr update.  This is based on the similar
change in PCM dshare, the commit faf53c197c.

There was a bug in the commit 38a2d2eda8 regarding the PCM state
change, and it was addressed in commit 3752e6b873 ("pcm: dmix: Fix
the inconsistent PCM state").  However, we've hit yet another bug in
this commit.  Namely, the hwptr update was forgotten in the
snd_pcm_dmix_sync_ptr0() function.  So the hwptr value passed from
snd_pcm_dmix_status() isn't properly stored, and it screws up at some
long run occasionally.

This patch covers the bug by replacing with the right value.

Fixes: 38a2d2eda8 ("pcm: dmix: Do not discard slave reported delay in status result")
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200013
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-06-12 13:55:20 +02:00
Jaroslav Kysela
ad5aea8922 pcm ioplug: fix some coverity issues (switch, missing unlock in snd_pcm_ioplug_drain())
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2018-05-23 10:59:40 +02:00