*参照元 [#j2012192] #backlinks *説明 [#y67d0d49] -パス: [[alsa-lib-1.0.27.2/src/pcm/pcm_hw.c]] -FIXME: これは何? --説明 **引数 [#d001f79f] -snd_pcm_t **pcmp -- --[[alsa-lib-1.0.27.2/snd_pcm_t]] -const char *name -- -int card -- -int device -- -int subdevice -- -snd_pcm_stream_t stream -- --[[alsa-lib-1.0.27.2/snd_pcm_stream_t]] -int mode -- -int mmap_emulation ATTRIBUTE_UNUSED -- --[[alsa-lib-1.0.27.2/ATTRIBUTE_UNUSED]] -int sync_ptr_ioctl -- **返り値 [#i0c7a5c3] -int -- **参考 [#s862ce10] *実装 [#q41acca7] /** * \brief Creates a new hw PCM * \param pcmp Returns created PCM handle * \param name Name of PCM * \param card Number of card * \param device Number of device * \param subdevice Number of subdevice * \param stream PCM Stream * \param mode PCM Mode * \param mmap_emulation Obsoleted parameter * \param sync_ptr_ioctl Use SYNC_PTR ioctl rather than mmap for control structures * \retval zero on success otherwise a negative error code * \warning Using of this function might be dangerous in the sense * of compatibility reasons. The prototype might be freely * changed in future. */ int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, int card, int device, int subdevice, snd_pcm_stream_t stream, int mode, int mmap_emulation ATTRIBUTE_UNUSED, int sync_ptr_ioctl) { char filename[sizeof(SNDRV_FILE_PCM_STREAM_PLAYBACK) + 20]; const char *filefmt; int ret = 0, fd = -1; int attempt = 0; snd_pcm_info_t info; int fmode; snd_ctl_t *ctl; - --[[alsa-lib-1.0.27.2/SNDRV_FILE_PCM_STREAM_PLAYBACK]] - --[[alsa-lib-1.0.27.2/snd_pcm_info_t]] - --[[alsa-lib-1.0.27.2/snd_ctl_t]] assert(pcmp); if ((ret = snd_ctl_hw_open(&ctl, NULL, card, 0)) < 0) return ret; - --[[alsa-lib-1.0.27.2/snd_ctl_hw_open()]] switch (stream) { case SND_PCM_STREAM_PLAYBACK: filefmt = SNDRV_FILE_PCM_STREAM_PLAYBACK; break; case SND_PCM_STREAM_CAPTURE: filefmt = SNDRV_FILE_PCM_STREAM_CAPTURE; break; default: SNDERR("invalid stream %d", stream); return -EINVAL; } sprintf(filename, filefmt, card, device); -プレイバック(再生)の場合は、/dev/snd/pcmC0D0p のようなファイル名になる。 --[[alsa-lib-1.0.27.2/SND_PCM_STREAM_PLAYBACK]] --[[alsa-lib-1.0.27.2/SNDRV_FILE_PCM_STREAM_PLAYBACK]] -キャプチャ(録音)の場合は、/dev/snd/pcmC0D0c のようなファイル名になる。 --[[alsa-lib-1.0.27.2/SND_PCM_STREAM_CAPTURE]] --[[alsa-lib-1.0.27.2/SNDRV_FILE_PCM_STREAM_CAPTURE]] -プレイバックでもキャプチャでもないならエラー。 -ファイル名を生成する。 --プレイバック(再生)の場合は、/dev/snd/pcmC0D0p のようなファイル名になる。 ---[[alsa-lib-1.0.27.2/SND_PCM_STREAM_PLAYBACK]] ---[[alsa-lib-1.0.27.2/SNDRV_FILE_PCM_STREAM_PLAYBACK]] --キャプチャ(録音)の場合は、/dev/snd/pcmC0D0c のようなファイル名になる。 ---[[alsa-lib-1.0.27.2/SND_PCM_STREAM_CAPTURE]] ---[[alsa-lib-1.0.27.2/SNDRV_FILE_PCM_STREAM_CAPTURE]] --プレイバックでもキャプチャでもないならエラー。 --[[alsa-lib-1.0.27.2/SNDERR()]] __again: if (attempt++ > 3) { ret = -EBUSY; goto _err; } ret = snd_ctl_pcm_prefer_subdevice(ctl, subdevice); if (ret < 0) goto _err; - -サブデバイスを選択する。 --[[alsa-lib-1.0.27.2/snd_ctl_pcm_prefer_subdevice()]] fmode = O_RDWR; if (mode & SND_PCM_NONBLOCK) fmode |= O_NONBLOCK; if (mode & SND_PCM_ASYNC) fmode |= O_ASYNC; if (mode & SND_PCM_APPEND) fmode |= O_APPEND; - --[[alsa-lib-1.0.27.2/SND_PCM_NONBLOCK]] - --[[alsa-lib-1.0.27.2/SND_PCM_ASYNC]] - --[[alsa-lib-1.0.27.2/SND_PCM_APPEND]] fd = snd_open_device(filename, fmode); if (fd < 0) { ret = -errno; SYSMSG("open '%s' failed (%i)", filename, ret); goto _err; } - -先ほど生成したファイル名を使って、デバイスファイルを開く。 --[[alsa-lib-1.0.27.2/snd_open_device()]] - --[[alsa-lib-1.0.27.2/SYSMSG()]] if (subdevice >= 0) { memset(&info, 0, sizeof(info)); if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, &info) < 0) { ret = -errno; SYSMSG("SNDRV_PCM_IOCTL_INFO failed (%i)", ret); goto _err; } if (info.subdevice != (unsigned int) subdevice) { close(fd); goto __again; } } - -パラメータにより指定されたサブデバイス番号を選択できたかどうか確かめる。 --[[alsa-lib-1.0.27.2/SNDRV_PCM_IOCTL_INFO]] snd_ctl_close(ctl); return snd_pcm_hw_open_fd(pcmp, name, fd, 0, sync_ptr_ioctl); - --[[alsa-lib-1.0.27.2/snd_ctl_close()]] - --[[alsa-lib-1.0.27.2/snd_pcm_hw_open_fd()]] _err: snd_ctl_close(ctl); return ret; } *コメント [#nd050e34]