linux-2.6.33/snd_pcm_lib_read1()
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
*参照元 [#hf0c8264]
#backlinks
*説明 [#v168b9fc]
-パス: [[linux-2.6.33/sound/core/pcm_lib.c]]
-FIXME: これは何?
--説明
**引数 [#y7fda71b]
-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]]
**返り値 [#jbcb75e4]
-snd_pcm_sframes_t
--
--[[linux-2.6.33/snd_pcm_sframes_t]]
**参考 [#j9421802]
*実装 [#vd4afecb]
static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pc...
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:
if (size >= runtime->start_threshold) {
err = snd_pcm_start(substream);
if (err < 0)
goto _end_unlock;
}
-
--[[linux-2.6.33/SNDRV_PCM_STATE_PREPARED]]
-
--[[linux-2.6.33/snd_pcm_start()]]
break;
case SNDRV_PCM_STATE_DRAINING:
case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_PAUSED:
break;
-
--[[linux-2.6.33/SNDRV_PCM_STATE_DRAINING]]
-
--[[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_capture_avail(runtime);
-
--[[linux-2.6.33/snd_pcm_capture_avail()]]
if (!avail) {
if (runtime->status->state ==
SNDRV_PCM_STATE_DRAINING) {
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
goto _end_unlock;
}
-
--[[linux-2.6.33/snd_pcm_stop()]]
-
--[[linux-2.6.33/SNDRV_PCM_STATE_SETUP]]
if (nonblock) {
err = -EAGAIN;
goto _end_unlock;
}
err = wait_for_avail_min(substream, &avail);
if (err < 0)
goto _end_unlock;
if (!avail)
continue; /* draining */
-
--[[linux-2.6.33/wait_for_avail_min()]]
}
frames = size > avail ? avail : size;
cont = runtime->buffer_size - runtime->control->appl_p...
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_BUG_ON()]]
-
--[[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,...
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;
}
_end_unlock:
snd_pcm_stream_unlock_irq(substream);
_end:
return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
}
*コメント [#gf5a9c79]
終了行:
*参照元 [#hf0c8264]
#backlinks
*説明 [#v168b9fc]
-パス: [[linux-2.6.33/sound/core/pcm_lib.c]]
-FIXME: これは何?
--説明
**引数 [#y7fda71b]
-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]]
**返り値 [#jbcb75e4]
-snd_pcm_sframes_t
--
--[[linux-2.6.33/snd_pcm_sframes_t]]
**参考 [#j9421802]
*実装 [#vd4afecb]
static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pc...
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:
if (size >= runtime->start_threshold) {
err = snd_pcm_start(substream);
if (err < 0)
goto _end_unlock;
}
-
--[[linux-2.6.33/SNDRV_PCM_STATE_PREPARED]]
-
--[[linux-2.6.33/snd_pcm_start()]]
break;
case SNDRV_PCM_STATE_DRAINING:
case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_PAUSED:
break;
-
--[[linux-2.6.33/SNDRV_PCM_STATE_DRAINING]]
-
--[[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_capture_avail(runtime);
-
--[[linux-2.6.33/snd_pcm_capture_avail()]]
if (!avail) {
if (runtime->status->state ==
SNDRV_PCM_STATE_DRAINING) {
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
goto _end_unlock;
}
-
--[[linux-2.6.33/snd_pcm_stop()]]
-
--[[linux-2.6.33/SNDRV_PCM_STATE_SETUP]]
if (nonblock) {
err = -EAGAIN;
goto _end_unlock;
}
err = wait_for_avail_min(substream, &avail);
if (err < 0)
goto _end_unlock;
if (!avail)
continue; /* draining */
-
--[[linux-2.6.33/wait_for_avail_min()]]
}
frames = size > avail ? avail : size;
cont = runtime->buffer_size - runtime->control->appl_p...
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_BUG_ON()]]
-
--[[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,...
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;
}
_end_unlock:
snd_pcm_stream_unlock_irq(substream);
_end:
return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
}
*コメント [#gf5a9c79]
ページ名: