Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5de9e45f authored by Jaroslav Kysela's avatar Jaroslav Kysela
Browse files

ALSA: snd-aloop - add pause support



Signed-off-by: default avatarJaroslav Kysela <perex@perex.cz>
parent dd04bb12
Loading
Loading
Loading
Loading
+22 −5
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ struct loopback_cable {
	/* flags */
	unsigned int valid;
	unsigned int running;
	unsigned int pause;
};

struct loopback_setup {
@@ -254,7 +255,7 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct loopback_pcm *dpcm = runtime->private_data;
	struct loopback_cable *cable = dpcm->cable;
	int err;
	int err, stream = 1 << substream->stream;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
@@ -264,7 +265,8 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
		dpcm->last_jiffies = jiffies;
		dpcm->pcm_rate_shift = 0;
		spin_lock(&cable->lock);	
		cable->running |= (1 << substream->stream);
		cable->running |= stream;
		cable->pause &= ~stream;
		spin_unlock(&cable->lock);
		loopback_timer_start(dpcm);
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -272,12 +274,26 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		spin_lock(&cable->lock);	
		cable->running &= ~(1 << substream->stream);
		cable->running &= ~stream;
		cable->pause &= ~stream;
		spin_unlock(&cable->lock);
		loopback_timer_stop(dpcm);
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
			loopback_active_notify(dpcm);
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		spin_lock(&cable->lock);	
		cable->pause |= stream;
		spin_unlock(&cable->lock);
		loopback_timer_stop(dpcm);
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		spin_lock(&cable->lock);
		dpcm->last_jiffies = jiffies;
		cable->pause &= ~stream;
		spin_unlock(&cable->lock);
		loopback_timer_start(dpcm);
		break;
	default:
		return -EINVAL;
	}
@@ -468,7 +484,7 @@ static unsigned int loopback_pos_update(struct loopback_cable *cable)
	unsigned int running;

	spin_lock(&cable->lock);	
	running = cable->running;
	running = cable->running ^ cable->pause;
	if (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) {
		delta_play = jiffies - dpcm_play->last_jiffies;
		dpcm_play->last_jiffies += delta_play;
@@ -532,7 +548,7 @@ static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
static struct snd_pcm_hardware loopback_pcm_hardware =
{
	.info =		(SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
			 SNDRV_PCM_INFO_MMAP_VALID),
			 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
	.formats =	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
			 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |
			 SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE),
@@ -1060,6 +1076,7 @@ static void print_substream_info(struct snd_info_buffer *buffer,
	}
	snd_iprintf(buffer, "  valid: %u\n", cable->valid);
	snd_iprintf(buffer, "  running: %u\n", cable->running);
	snd_iprintf(buffer, "  pause: %u\n", cable->pause);
	print_dpcm_info(buffer, cable->streams[0], "Playback");
	print_dpcm_info(buffer, cable->streams[1], "Capture");
}