All of lore.kernel.org
 help / color / mirror / Atom feed
* then there was "overrun" occue every time once trigger the audio recording
@ 2012-07-06 10:00 Zhen Fu
  0 siblings, 0 replies; 5+ messages in thread
From: Zhen Fu @ 2012-07-06 10:00 UTC (permalink / raw)
  To: Clemens Ladisch; +Cc: alsa-devel, Zhen Fu

Hi Clemens,



Your answer is very useful to help me. Thank you very much.



>     case AUDIO_STREAM_CMDID_DATARXTXREQ:

>           len1 = get_zsp_buf_avail(&prtd->zsp_buf);

>           len2 = get_fw_avail(p_zsp_req, substream->stream);

>           len3 = get_buf_avail(&prtd->zsp_buf, substream->stream);

>           tsize = ((len1 < len2) ? len1 : len2);

>           if ((tsize == len1) && (len1 == len3) && (tsize >= \

>                 2 * prtd->zsp_buf.zsp_period_bytes)) {

>                 tsize -= prtd->zsp_buf.zsp_period_bytes;

>           }



>     This doesn't look as if tsize is always the same as the period size.

>     And what do the get_fw_avail and get_buf_avail functions do?



The ZSP have own buffer to save data, so get_fw_avail is acquired zsp buf avial.

And ZSP buffer must ensure the zsp_buf have sequenced, so do above process.

--
Best Regards,
Zhen Fu

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: then there was "overrun" occue every time once trigger the audio recording
  2012-07-06  7:51   ` Zhen Fu
@ 2012-07-06  8:23     ` Clemens Ladisch
  0 siblings, 0 replies; 5+ messages in thread
From: Clemens Ladisch @ 2012-07-06  8:23 UTC (permalink / raw)
  To: Zhen Fu; +Cc: alsa-devel

(please configure your mailer to wrap lines; and please don't top-post!)

Zhen Fu wrote:
> When ALSA send AUDIO_STREAM_CMDID_TRIGGER command to ZSP, ZSP firmware
> do config something and then send AUDIO_STREAM_CMDID_DATARXTXREQ
> command to ALSA, then the ALSA send write/read pointer to ZSP, the ZSP
> through write/read pointer to fetch/transfer data, after process the
> ZSP send AUDIO_STREAM_CMDID_DATARXTX command to ALSA, then the ALSA
> change write/read pointer.

This is not exactly how the driver actually works.

> mmp_zsp_pcm_pointer(struct snd_pcm_substream *substream)
> 	...
> 	x = bytes_to_frames(runtime, x);
> 	if (x == prtd->zsp_buf.buf_len/4)
> 		x = 0;

This assumes that there are four bytes per frame.
If you move the if before the bytes_to_frames, you can use
"if (x == prtd->zsp_buf.buf_len)" which is correct for any frame size.

> 	case AUDIO_STREAM_CMDID_DATARXTX:
> 			snd_pcm_period_elapsed(substream);

Please note that this call must be at the end of each period,
i.e., this code is correct only if each DATARXTX command
transfers exactly one period.

> 	case AUDIO_STREAM_CMDID_DATARXTXREQ:
> 		len1 = get_zsp_buf_avail(&prtd->zsp_buf);
> 		len2 = get_fw_avail(p_zsp_req, substream->stream);
> 		len3 = get_buf_avail(&prtd->zsp_buf, substream->stream);
> 		tsize = ((len1 < len2) ? len1 : len2);
> 		if ((tsize == len1) && (len1 == len3) && (tsize >= \
> 			2 * prtd->zsp_buf.zsp_period_bytes)) {
> 			tsize -= prtd->zsp_buf.zsp_period_bytes;
> 		}

This doesn't look as if tsize is always the same as the period size.
And what do the get_fw_avail and get_buf_avail functions do?

> 		if ((prtd->zsp_buf.zsp_offset + tsize) >= \
> 				(prtd->zsp_buf.buf_len))
> 				prtd->zsp_buf.zsp_offset = 0;
> 		else
> 			prtd->zsp_buf.zsp_offset += \
> 					tsize;

The pointer callback can be called at any time, so you should ensure
that zsp_offset has the correct value at all times, i.e., it should
be updated only after the bytes have actually be transferred, in the
AUDIO_STREAM_CMDID_DATARXTX handler.

That handler should look something like this:

	case AUDIO_STREAM_CMDID_DATARXTX:
		/* determine how many bytes have been transferred */
		tsize = ...;

		spin_lock_irqsave(...);
		mydevice->zsp_offset += tsize;
		if (mydevice->zsp_offset >= buffer_bytes)
			mydevice->zsp_offset -= buffer_bytes;
		spin_lock_irqrestore(...);

		mydevice->period_offset += tsize;
		if (mydevice->period_offset >= period_bytes) {
			mydevice->period_offset -= period_bytes;
			snd_pcm_period_elapsed();
		}

The last check works correctly only if transfers are never
larger than one period.

If the DATARXTX handler and the period callback can be executed
concurrently (which is likely), you need to add locking to both
of them to protect zsp_offset.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: then there was "overrun" occue every time once trigger the audio recording
  2012-07-06  7:17 ` Clemens Ladisch
@ 2012-07-06  7:51   ` Zhen Fu
  2012-07-06  8:23     ` Clemens Ladisch
  0 siblings, 1 reply; 5+ messages in thread
From: Zhen Fu @ 2012-07-06  7:51 UTC (permalink / raw)
  To: Clemens Ladisch, alsa-devel; +Cc: Zhen Fu

Ok, I got it.

I use marvell pxa2128 chip include ZSP core that connection codec, my aim to let zsp complete independence alsa work. 
When ALSA send AUDIO_STREAM_CMDID_TRIGGER command to ZSP, ZSP firmware do config something and then send AUDIO_STREAM_CMDID_DATARXTXREQ command to ALSA, then the ALSA send write/read pointer to ZSP, the ZSP through write/read pointer to fetch/transfer data, after process the ZSP send AUDIO_STREAM_CMDID_DATARXTX command to ALSA, then the ALSA change write/read pointer. My driver code below:

static snd_pcm_uframes_t
mmp_zsp_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct pxa910_runtime_data *prtd = runtime->private_data;
	snd_pcm_uframes_t x;

	x = prtd->zsp_buf.zsp_offset;
	x = bytes_to_frames(runtime, x);
	if (x == prtd->zsp_buf.buf_len/4)
		x = 0;

	return x;
}

static void zsp_msg_handler(struct work_struct *work) {
	......
	.....
	case AUDIO_STREAM_CMDID_DATARXTXREQ:
		p_zsp_req = (cmd_audio_stream_datarxtxreq_t *)\
				&zsp_data_received;
		len1 = get_zsp_buf_avail(&prtd->zsp_buf);
		len2 = get_fw_avail(p_zsp_req, substream->stream);
		len3 = get_buf_avail(&prtd->zsp_buf, substream->stream);
		tsize = ((len1 < len2) ? len1 : len2);
		if ((tsize == len1) && (len1 == len3) && (tsize >= \
			2 * prtd->zsp_buf.zsp_period_bytes)) {
			tsize -= prtd->zsp_buf.zsp_period_bytes;
		}
		cmd_strm_tx.command_id = AUDIO_STREAM_CMDID_DATARXTX;
		cmd_strm_tx.stream_id = prtd->stream_id;
		cmd_strm_tx.addr = prtd->zsp_buf.buf_phys +	\
				prtd->zsp_buf.zsp_offset;
		cmd_strm_tx.size = tsize;
		kzmq_write(prtd->zmq_deliver, (void *)&cmd_strm_tx,
					   sizeof(cmd_audio_stream_datarxtx_t));
		if ((prtd->zsp_buf.zsp_offset + tsize) >= \
				(prtd->zsp_buf.buf_len))
				prtd->zsp_buf.zsp_offset = 0;
		else
			prtd->zsp_buf.zsp_offset += \
					tsize;
		break;
	case AUDIO_STREAM_CMDID_DATARXTX:
			snd_pcm_period_elapsed(substream);
			break;

}   

When I use arecord command occue "overrun", I don't know I explain problem clear or not. Thanks a lot.
--
Best Regards,
Zhen Fu

-----Original Message-----
From: alsa-devel-bounces@alsa-project.org [mailto:alsa-devel-bounces@alsa-project.org] On Behalf Of Clemens Ladisch
Sent: Friday, July 06, 2012 3:17 PM
To: alsa-devel@alsa-project.org
Subject: Re: [alsa-devel] then there was "overrun" occue every time once trigger the audio recording

(please configure your mailer to wrap lines)

Zhen Fu wrote:
> When I use arecord command, then there was "overrun" occue every time
> once trigger the audio recording.  I have no clue of alsa driver when
> and how handler xrun. In other words, how to understand function
> snd_pcm_update_hw_ptr0 in pcm_lib.c.

It behaves pretty much the same for playback and capture, so I refer
the honourable gentleman to the reply I gave some moments ago.

If you want a more specific answer, it might be a good idea not to
keep the hardware and your driver source code a secret.


Regards,
Clemens
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: then there was "overrun" occue every time once trigger the audio recording
  2012-07-06  2:28 Zhen Fu
@ 2012-07-06  7:17 ` Clemens Ladisch
  2012-07-06  7:51   ` Zhen Fu
  0 siblings, 1 reply; 5+ messages in thread
From: Clemens Ladisch @ 2012-07-06  7:17 UTC (permalink / raw)
  To: alsa-devel

(please configure your mailer to wrap lines)

Zhen Fu wrote:
> When I use arecord command, then there was "overrun" occue every time
> once trigger the audio recording.  I have no clue of alsa driver when
> and how handler xrun. In other words, how to understand function
> snd_pcm_update_hw_ptr0 in pcm_lib.c.

It behaves pretty much the same for playback and capture, so I refer
the honourable gentleman to the reply I gave some moments ago.

If you want a more specific answer, it might be a good idea not to
keep the hardware and your driver source code a secret.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 5+ messages in thread

* then there was "overrun" occue every time once trigger the audio recording
@ 2012-07-06  2:28 Zhen Fu
  2012-07-06  7:17 ` Clemens Ladisch
  0 siblings, 1 reply; 5+ messages in thread
From: Zhen Fu @ 2012-07-06  2:28 UTC (permalink / raw)
  To: alsa-devel; +Cc: Zhen Fu

Hi developer,

When I use arecord command, then there was "overrun" occue every time once trigger the audio recording. I have no clue of alsa driver when and how handler xrun. In other words, how to understand function snd_pcm_update_hw_ptr0 in pcm_lib.c. Please enlighten me on this issue. Thanks a lot in advance.

--
Best Regards,
Zhen Fu

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-07-06 10:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-06 10:00 then there was "overrun" occue every time once trigger the audio recording Zhen Fu
  -- strict thread matches above, loose matches on Subject: below --
2012-07-06  2:28 Zhen Fu
2012-07-06  7:17 ` Clemens Ladisch
2012-07-06  7:51   ` Zhen Fu
2012-07-06  8:23     ` Clemens Ladisch

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.