mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	Add snd_pcm_avail() and snd_pcm_avail_delay() functions. Make snd_pcm_hwsync() deprecated.
As proposed in http://mailman.alsa-project.org/pipermail/alsa-devel/2008-June/008558.html the snd_pcm_avail() and snd_pcm_avail_delay() functions are now available to get accurate stream position in a straight way. The snd_pcm_avail_delay() function was added to ensure full sync between avail and delay values. It's actually implemented using delay() + avail_update() calls but it might be changed in future. Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
		
							parent
							
								
									8d6838450a
								
							
						
					
					
						commit
						fe5391c9da
					
				
					 1 changed files with 85 additions and 10 deletions
				
			
		| 
						 | 
				
			
			@ -394,6 +394,7 @@ call.
 | 
			
		|||
 | 
			
		||||
\subsection pcm_status_fast Obtaining stream state fast and update r/w pointer
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
The function #snd_pcm_avail_update() updates the current
 | 
			
		||||
available count of samples for writing (playback) or filled samples for
 | 
			
		||||
reading (capture). This call is mandatory for updating actual r/w pointer.
 | 
			
		||||
| 
						 | 
				
			
			@ -401,15 +402,12 @@ Using standalone, it is a light method to obtain current stream position,
 | 
			
		|||
because it does not require the user <-> kernel context switch, but the value
 | 
			
		||||
is less accurate, because ring buffer pointers are updated in kernel drivers
 | 
			
		||||
only when an interrupt occurs. If you want to get accurate stream state,
 | 
			
		||||
use functions #snd_pcm_hwsync() or #snd_pcm_delay().
 | 
			
		||||
Note that both of these functions do not update the current r/w pointer
 | 
			
		||||
for applications, so the function #snd_pcm_avail_update() must
 | 
			
		||||
be called afterwards before any read/write begin+commit operations.
 | 
			
		||||
use functions #snd_pcm_avail(), #snd_pcm_delay() or #snd_pcm_avail_delay().
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
The function #snd_pcm_hwsync() reads the current hardware pointer
 | 
			
		||||
in the ring buffer from hardware. Note that this function does not update the current
 | 
			
		||||
r/w pointer for applications, so the function #snd_pcm_avail_update()
 | 
			
		||||
must be called afterwards before any read/write/begin+commit operations.
 | 
			
		||||
The function #snd_pcm_avail() reads the current hardware pointer
 | 
			
		||||
in the ring buffer from hardware and calls #snd_pcm_avail_update() then.
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
The function #snd_pcm_delay() returns the delay in samples.
 | 
			
		||||
For playback, it means count of samples in the ring buffer before
 | 
			
		||||
| 
						 | 
				
			
			@ -419,6 +417,11 @@ only when the stream is in the running or draining (playback only) state.
 | 
			
		|||
Note that this function does not update the current r/w pointer for applications,
 | 
			
		||||
so the function #snd_pcm_avail_update() must be called afterwards
 | 
			
		||||
before any read/write begin+commit operations.
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
The function #snd_pcm_avail_delay() combines #snd_pcm_avail() and
 | 
			
		||||
#snd_pcm_delay() and returns both values in sync.
 | 
			
		||||
</p>
 | 
			
		||||
 | 
			
		||||
\section pcm_action Managing the stream state
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -915,7 +918,7 @@ snd_pcm_state_t snd_pcm_state(snd_pcm_t *pcm)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Synchronize stream position with hardware
 | 
			
		||||
 * \brief (DEPRECATED) Synchronize stream position with hardware
 | 
			
		||||
 * \param pcm PCM handle
 | 
			
		||||
 * \return 0 on success otherwise a negative error code
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -932,6 +935,9 @@ int snd_pcm_hwsync(snd_pcm_t *pcm)
 | 
			
		|||
	}
 | 
			
		||||
	return pcm->fast_ops->hwsync(pcm->fast_op_arg);
 | 
			
		||||
}
 | 
			
		||||
#ifndef DOC_HIDDEN
 | 
			
		||||
link_warning(snd_pcm_hwsync, "Warning: snd_pcm_hwsync() is deprecated, consider to use snd_pcm_avail()");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Obtain delay for a running PCM handle
 | 
			
		||||
| 
						 | 
				
			
			@ -953,7 +959,7 @@ int snd_pcm_hwsync(snd_pcm_t *pcm)
 | 
			
		|||
 * necessarily got down to 0.
 | 
			
		||||
 *
 | 
			
		||||
 * If the application is interested in the fill level of the playback buffer
 | 
			
		||||
 * of the device, it should use snd_pcm_avail_update(). The
 | 
			
		||||
 * of the device, it should use #snd_pcm_avail*() functions. The
 | 
			
		||||
 * value returned by that call is not directly related to the delay, since the
 | 
			
		||||
 * latter might include some additional, fixed latencies the former does not.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -2404,12 +2410,81 @@ int snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout)
 | 
			
		|||
 *
 | 
			
		||||
 * On capture does all the actions needed to transport to application
 | 
			
		||||
 * level all the ready frames across underlying layers.
 | 
			
		||||
 *
 | 
			
		||||
 * The position is not synced with hardware (driver) position in the sound
 | 
			
		||||
 * ring buffer in this function. This function is a light version of
 | 
			
		||||
 * #snd_pcm_avail() .
 | 
			
		||||
 *
 | 
			
		||||
 * Using this function is ideal after poll() or select() when audio
 | 
			
		||||
 * file descriptor made the event and when application expects just period
 | 
			
		||||
 * timing.
 | 
			
		||||
 *
 | 
			
		||||
 * Also this function might be called after #snd_pcm_delay() or
 | 
			
		||||
 * #snd_pcm_hwsync() functions to move private ring buffer pointers
 | 
			
		||||
 * in alsa-lib (the internal plugin chain).
 | 
			
		||||
 */
 | 
			
		||||
snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm)
 | 
			
		||||
{
 | 
			
		||||
	return pcm->fast_ops->avail_update(pcm->fast_op_arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Return number of frames ready to be read (capture) / written (playback)
 | 
			
		||||
 * \param pcm PCM handle
 | 
			
		||||
 * \return a positive number of frames ready otherwise a negative
 | 
			
		||||
 * error code
 | 
			
		||||
 *
 | 
			
		||||
 * On capture does all the actions needed to transport to application
 | 
			
		||||
 * level all the ready frames across underlying layers.
 | 
			
		||||
 *
 | 
			
		||||
 * The position is synced with hardware (driver) position in the sound
 | 
			
		||||
 * ring buffer in this functions.
 | 
			
		||||
 */
 | 
			
		||||
snd_pcm_sframes_t snd_pcm_avail(snd_pcm_t *pcm)
 | 
			
		||||
{
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	assert(pcm);
 | 
			
		||||
	if (CHECK_SANITY(! pcm->setup)) {
 | 
			
		||||
		SNDMSG("PCM not set up");
 | 
			
		||||
		return -EIO;
 | 
			
		||||
	}
 | 
			
		||||
	err = pcm->fast_ops->hwsync(pcm->fast_op_arg);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
		return err;
 | 
			
		||||
	return pcm->fast_ops->avail_update(pcm->fast_op_arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Combine snd_pcm_avail and snd_pcm_delay functions
 | 
			
		||||
 * \param pcm PCM handle
 | 
			
		||||
 * \param avail Number of available frames in the ring buffer
 | 
			
		||||
 * \param delay Total I/O latency in frames
 | 
			
		||||
 * \return zero on success otherwise a negative error code
 | 
			
		||||
 *
 | 
			
		||||
 * The avail and delay values retuned are in sync.
 | 
			
		||||
 */
 | 
			
		||||
int snd_pcm_avail_delay(snd_pcm_t *pcm,
 | 
			
		||||
			snd_pcm_sframes_t *availp,
 | 
			
		||||
			snd_pcm_sframes_t *delayp)
 | 
			
		||||
{
 | 
			
		||||
	snd_pcm_sframes_t sf;
 | 
			
		||||
 | 
			
		||||
	assert(pcm && availp && delayp);
 | 
			
		||||
	if (CHECK_SANITY(! pcm->setup)) {
 | 
			
		||||
		SNDMSG("PCM not set up");
 | 
			
		||||
		return -EIO;
 | 
			
		||||
	}
 | 
			
		||||
	sf = pcm->fast_ops->delay(pcm->fast_op_arg, delayp);
 | 
			
		||||
	if (sf < 0)
 | 
			
		||||
		return (int)sf;
 | 
			
		||||
	sf = pcm->fast_ops->avail_update(pcm->fast_op_arg);
 | 
			
		||||
	if (sf < 0)
 | 
			
		||||
		return (int)sf;
 | 
			
		||||
	*availp = sf;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Silence an area
 | 
			
		||||
 * \param dst_area area specification
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue