*参照元 [#bde04a00]
#backlinks

*説明 [#a08d9573]
-パス: [[linux-2.6.33/sound/core/pcm_lib.c]]

-FIXME: これは何?
--説明


**引数 [#y62f3299]
-struct snd_pcm_substream *substream
--
--[[linux-2.6.33/snd_pcm_substream]]
-unsigned long data
--
-snd_pcm_uframes_t size
--
--[[linux-2.6.33/snd_pcm_uframes_t]]
-int nonblock
--
-transfer_f transfer
--
--[[linux-2.6.33/transfer_f]]


**返り値 [#u18e23af]
-snd_pcm_sframes_t
--
--[[linux-2.6.33/snd_pcm_sframes_t]]


**参考 [#cd0cf823]


*実装 [#s8bfdbad]
 static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, 
 					    unsigned long data,
 					    snd_pcm_uframes_t size,
 					    int nonblock,
 					    transfer_f transfer)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t xfer = 0;
 	snd_pcm_uframes_t offset = 0;
 	int err = 0;
 
-
--[[linux-2.6.33/snd_pcm_runtime]]

 	if (size == 0)
 		return 0;
 
 	snd_pcm_stream_lock_irq(substream);
-
--[[linux-2.6.33/snd_pcm_stream_lock_irq()]]

 	switch (runtime->status->state) {
 	case SNDRV_PCM_STATE_PREPARED:
 	case SNDRV_PCM_STATE_RUNNING:
 	case SNDRV_PCM_STATE_PAUSED:
 		break;
-
--[[linux-2.6.33/SNDRV_PCM_STATE_PREPARED]]
-
--[[linux-2.6.33/SNDRV_PCM_STATE_RUNNING]]
-
--[[linux-2.6.33/SNDRV_PCM_STATE_PAUSED]]

 	case SNDRV_PCM_STATE_XRUN:
 		err = -EPIPE;
 		goto _end_unlock;
-
--[[linux-2.6.33/SNDRV_PCM_STATE_XRUN]]

 	case SNDRV_PCM_STATE_SUSPENDED:
 		err = -ESTRPIPE;
 		goto _end_unlock;
-
--[[linux-2.6.33/SNDRV_PCM_STATE_SUSPENDED]]

 	default:
 		err = -EBADFD;
 		goto _end_unlock;
 	}
 
 	while (size > 0) {
 		snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
 		snd_pcm_uframes_t avail;
 		snd_pcm_uframes_t cont;
 		if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
 			snd_pcm_update_hw_ptr(substream);
-
--[[linux-2.6.33/snd_pcm_update_hw_ptr()]]

 		avail = snd_pcm_playback_avail(runtime);
-
--[[linux-2.6.33/snd_pcm_playback_avail()]]

 		if (!avail) {
 			if (nonblock) {
 				err = -EAGAIN;
 				goto _end_unlock;
 			}
 			err = wait_for_avail_min(substream, &avail);
 			if (err < 0)
 				goto _end_unlock;
 		}
-
--[[linux-2.6.33/wait_for_avail_min()]]

 		frames = size > avail ? avail : size;
 		cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
 		if (frames > cont)
 			frames = cont;
 		if (snd_BUG_ON(!frames)) {
 			snd_pcm_stream_unlock_irq(substream);
 			return -EINVAL;
 		}
-
--runtime->control は snd_pcm_mmap_control 型
--[[linux-2.6.33/snd_pcm_mmap_control]]
-
--[[linux-2.6.33/snd_pcm_stream_unlock_irq()]]

 		appl_ptr = runtime->control->appl_ptr;
 		appl_ofs = appl_ptr % runtime->buffer_size;
 		snd_pcm_stream_unlock_irq(substream);
 		if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0)
 			goto _end;
 		snd_pcm_stream_lock_irq(substream);
 		switch (runtime->status->state) {
 		case SNDRV_PCM_STATE_XRUN:
 			err = -EPIPE;
 			goto _end_unlock;
 		case SNDRV_PCM_STATE_SUSPENDED:
 			err = -ESTRPIPE;
 			goto _end_unlock;
 		default:
 			break;
 		}
 		appl_ptr += frames;
 		if (appl_ptr >= runtime->boundary)
 			appl_ptr -= runtime->boundary;
 		runtime->control->appl_ptr = appl_ptr;
 		if (substream->ops->ack)
 			substream->ops->ack(substream);
 
-
--substream->ops は snd_pcm_ops 型のメンバ
--[[linux-2.6.33/snd_pcm_ops]]

 		offset += frames;
 		size -= frames;
 		xfer += frames;
 		if (runtime->status->state == SNDRV_PCM_STATE_PREPARED &&
 		    snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) {
 			err = snd_pcm_start(substream);
 			if (err < 0)
 				goto _end_unlock;
 		}
-
--[[linux-2.6.33/snd_pcm_start()]]

 	}
  _end_unlock:
 	snd_pcm_stream_unlock_irq(substream);
  _end:
 	return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
 }


*コメント [#wada1da6]


トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS