A slave PCM in OPEN or DISCONNECTED state can't be used properly at
all, so the best option is to return -EBADFD error.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The previous commit removed the whole handling of resume in dmix, but
this seems causing another regression; some buggy drivers assume that
the device-resume needs to be triggered before transitioning to
PREPARED state. As an ugly workaround, in this patch, when the slave
PCM supports resume, snd_pcm_direct_resume() does resume of the slave
PCM but immediately drop the stream after that. In that way, the
device is brought to the sane active state, then the apps can prepare
and restart the stream properly.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
PCM dmix and other plugins inherit the resume behavior from the slave
PCM. However, the resume on dmix can't work reliably even if the
slave PCM may do resume. The running state of each dmix stream is
individual and may be PREPARED or RUN_PENDING while the slave PCM is
already in RUNNING. And, when the slave PCM is resumed, the whole
samples that have been already mapped are also played back, even if
the corresponding dmix stream is still in SUSPENDED. Such
inconsistencies can't be avoided as long as we manage each stream
individually.
That said, dmix & co can't provide the proper resume support "by
design". For aligning with it, we should drop the whole resume code
and clear the PCM SND_PCM_INFO_RESUME flag.
Reported-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The dmix plugin and co may trigger the resume for each instance in
snd_pcm_direct_resume(). It means that the slave PCM gets resumed or
re-prepared/started by each opened dmix stream, and this may end up
with the doubly triggers even though the slave PCM has been already
resumed by another dmix stream.
For avoiding this conflicts, check the slave PCM state and resume only
when it's still in the suspended state. Meanwhile we keep the shadow
state updated no matter whether the slave was triggered or not.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The recent fix commit [8985742d91: pcm: dmix: Handle slave PCM xrun
and unexpected states properly] caused a regression in dmix and other
plugins regarding suspend/resume. For example, aplay endlessly prints
"Suspended. Trying resume. Done." message if suspend and resume are
performed in the middle of playback.
The reason is that the commit above changed the shadow PCM state
(dmix->state) to SUSPENDED when the slave PCM is in suspend, while it
doesn't restore the shadow state upon resume. Thus it appears as if
it's always suspended even after the resume is invoked.
The fix is just to add the proper update of the shadow state in
snd_pcm_direct_resume().
Reported-by: Shengjiu Wang <shengjiu.wang@freescale.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
As stated in manpage SHMCTL(2), shm_nattch is "No. of current attaches"
(i.e., number of processes attached to the shared memeory). If an
application uses alsa-lib and invokes fork() from a thread of the
application, there may be the following execution sequence:
1. execute the following statement:
pcm_direct.c:110: dmix->shmptr = shmat(dmix->shmid, 0, 0)
(shm_nattch becomes 1)
2. invoke fork() in some thread.
(shm_nattch becomes 2)
3. execute the following statement:
pcm_direct.c:122: if (buf.shm_nattch == 1)
4. execute the following statement:
pcm_direct.c:131: if (dmix->shmptr->magic != SND_PCM_DIRECT_MAGIC)
(As stated in manpage SHMGET(2), "When a new shared memory segment
is created, its contents are initialized to zero values", so
dmix->shmptr->magic is 0)
5. execute the following statements:
pcm_direct.c:132: snd_pcm_direct_shm_discard(dmix)
pcm_direct.c:133: return -EINVAL
The above execution sequence will cause the following error:
unable to create IPC shm instance
This error causes multimedia application has no sound. This error rarely
occurs, probability is about 1%.
More notes about this patch:
this patch tries to address the race above by changing the condition
to identify "the first user". Until now, the first user was
identified by checking shm_nattch. But this is racy, as stated in the
above.
In this version, we try to assign a shm at first without IPC_CREAT.
If this succeeds, we are not alone, so we must not be the first user.
Only when this fails, try to get a shmem with IPC_CREAT and IPC_EXCL.
If this succeeds, we are the first user. And, one more notable point
is that the race of this function call itself is protected by
semaphore in the caller side. The only point to avoid is the race
after shmget() and the first initialization, and this method should
work around that.
Signed-off-by: Qing Cai <bsiice@msn.com>
Signed-off-by: Qing Cai <caiqing@neusoft.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Currently, dmix & co plugins ignore the XRUN state of the slave PCM.
It's (supposedly) because dmix deals with the PCM in a free-wheel
mode, which is equivalent with XRUN. But, this difference (whether
the correct freewheel or XRUN) should be done by the kernel, and we
may have an XRUN state indeed (e.g. via xrun injection).
This patch fixes this lack of behavior, to handle PCM xrun and does
prepare when the slave PCM is in such a state.
Also, the patch consolidates the prepare callback for all dmix, dsnoop
and dshare plugins, and fix/cleanup a bit for dshare/dsnoop codes to
align with dsnoop code.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
When a slave PCM gets an error like XRUN, it stops and notifies with
SND_TIMER_EVENT_MSTOP event. But the current code filters out this
type and eventually hang due to the empty timer queue. The fix is to
just add this event type to the filter bit mask.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
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>
not doing so, leaves the pcm object in an inconsistent state since
'info' field is copied from the slave which is then used when
snd_pcm_hw_params_is_monotonic() is called.
For instance, when using dmix with aplay and an underrun is occuring, the following
info is returned:
underrun!!! (at least 1248687948.256 ms long)
Status:
state : XRUN
trigger_time: 1390347762.628483000
tstamp : 1390347766.184350000
delay : -635
avail : 15687
avail_max : 15675
now is computed from CLOCK_MONOTONIC while pcm status tstamps are from gettimeofday().
After the fix, underruns are still occuring on my setup but at least the displayed info
is correct:
underrun!!! (at least 7630.409 ms long)
Status:
state : XRUN
trigger_time: 7652.739201431
tstamp : 7660.369600636
delay : -624
avail : 15676
avail_max : 15664
Signed-off-by: Olivier Langlois <olivier@trillion01.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Instead of passing ambiguous integer array, define snd_pcm_chmap_t and
snd_pcm_chmap_query_t so that user can understand more easily which
element is for what.
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>
Add SETUP state checks and do modifications according latest ALSA driver
(passing wrong event identification).
ALSA bug#4914
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Call the slave snd_pcm_info() as long as possible in the direct plugins
(i.e. when the PCM device could be opened with O_APPEND mode).
This allows dmix/dsnoop as a salve for PCM hook controls.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
By doing this we move them from the .data section to .rodata setion,
or from .data.rel to .data.rel.ro.
The .rodata section is mapped directly from the on-disk file, which is
always a save, while .data.rel.ro is mapped directly when using
prelink, which is a save in a lot of cases.
Signed-off-by: Diego E. 'Flameeyes' Pettenò <flameeyes@gmail.com>
The direct plugins have the automatic format-detection feature but it
wasn't enabled properly in the interface. Now you can pass the format
"unchanged" to make the plugin detect a proper format.
This will change the default format of some drivers, such as, HD-audio.
PCM direct plugins didn't update the timestamp properly.
Now it always starts the slave PCM with MMAP tstamp_mode so that the
timestamp will be being updated. When a client is set up as MMAP
tstamp_mode as well, simply copy this slave timestamp. Otherwise
status callback calculates the current timestamp as usual.
Enabling the slowptr options does not make snd_pcm_delay() and related
functions much slower than they would have been with a hw device, while
disabling this option greatly reduces the accuracy of those functions,
thus creating more jitter in any media player application that
synchronizes its output to the sound device.
Therefore, it is preferrable to have this option enabled by default.
The old format tried to do something when the requested format was not
supported by the hardware, but did not actually select any other format.
Now we try to switch to any format supported by dmix, or any other
format when the plugin is not dmix.
The code to set the number of channels did not work when the requested
channel count was not available and when the min/max channel counts were
not identical.
Replacing the entire selection code with
snd_pcm_hw_params_set_channels_near() gives the same result in the cases
where it previously worked, and works in all other cases.
safe_strtoll() now accepts numbers in any base. It formerly assumed that
its input was a decimal number, which had the consequence that
hexadecimal or octal numbers would be parsed as strings when occurring
outside of parameter lists.
This obsoletes some workarounds in the file permission parsing code that
relied on this bug.
Introduce "max_periods" option to specify the max number of periods
per buffer to each plugin.
- When max_periods = -1, the fixed buffer size as the slave size is
used (old behavior).
- When max_periods = 0 (or 1), the number of periods is variable
between 2 and the slave buffer size.
- When max_periods greater than 2 is given, it specifies the max
periods of that pcm explicitly.
When no option is given in the PCM defintion, the value
"defaults.pcm.dmix_max_periods" is referred as default.
The default value is 0, as defined in alsa.conf.
You can override this in ~/.asoundrc or /etc/asound.conf as you like.
Fixed the noisy output of dmix with two (or less) periods.
The dmix tends to give noise or XRUN when running with two periods
because of its implementation nature. To avoid this, the start
position is aligned to the period size, so that the updates are synced
with interrupts of slave PCM.
snd_timer_tread struct is a bad design for 32/64bit compatibility,
and reading this struct on 32bit program returns zero. This results
in tight poll looping (bug#1938, #1945).
For avoiding this bug, now more bigger buffer is read to cover the
64bit tread struct, too. Also this optimizes the read without
checking -EAGAIN in the case both user-space and kernel have the same
tread size.