📄 pcm.c
字号:
snd_iprintf(buffer, "start_threshold: %lu\n", runtime->start_threshold); snd_iprintf(buffer, "stop_threshold: %lu\n", runtime->stop_threshold); snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); snd_pcm_stream_unlock_irq(substream);}static void snd_pcm_substream_proc_status_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer){ snd_pcm_substream_t *substream = (snd_pcm_substream_t *)entry->private_data; snd_pcm_runtime_t *runtime = substream->runtime; snd_pcm_status_t status; int err; if (!runtime) { snd_iprintf(buffer, "closed\n"); return; } memset(&status, 0, sizeof(status)); err = snd_pcm_status(substream, &status); if (err < 0) { snd_iprintf(buffer, "error %d\n", err); return; } snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state)); snd_iprintf(buffer, "trigger_time: %ld.%09ld\n", status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec); snd_iprintf(buffer, "tstamp : %ld.%09ld\n", status.tstamp.tv_sec, status.tstamp.tv_nsec); snd_iprintf(buffer, "delay : %ld\n", status.delay); snd_iprintf(buffer, "avail : %ld\n", status.avail); snd_iprintf(buffer, "avail_max : %ld\n", status.avail_max); snd_iprintf(buffer, "-----\n"); snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr); snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr);}#ifdef CONFIG_SND_DEBUGstatic void snd_pcm_xrun_debug_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer){ snd_pcm_str_t *pstr = (snd_pcm_str_t *)entry->private_data; snd_iprintf(buffer, "%d\n", pstr->xrun_debug);}static void snd_pcm_xrun_debug_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer){ snd_pcm_str_t *pstr = (snd_pcm_str_t *)entry->private_data; char line[64]; if (!snd_info_get_line(buffer, line, sizeof(line))) pstr->xrun_debug = simple_strtoul(line, NULL, 10);}#endifstatic int snd_pcm_stream_proc_init(snd_pcm_str_t *pstr){ snd_pcm_t *pcm = pstr->pcm; snd_info_entry_t *entry; char name[16]; sprintf(name, "pcm%i%c", pcm->device, pstr->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c'); if ((entry = snd_info_create_card_entry(pcm->card, name, pcm->card->proc_root)) == NULL) return -ENOMEM; entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); return -ENOMEM; } pstr->proc_root = entry; if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) { snd_info_set_text_ops(entry, pstr, 256, snd_pcm_stream_proc_info_read); if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); entry = NULL; } } pstr->proc_info_entry = entry;#ifdef CONFIG_SND_DEBUG if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug", pstr->proc_root)) != NULL) { entry->c.text.read_size = 64; entry->c.text.read = snd_pcm_xrun_debug_read; entry->c.text.write_size = 64; entry->c.text.write = snd_pcm_xrun_debug_write; entry->private_data = pstr; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); entry = NULL; } } pstr->proc_xrun_debug_entry = entry;#endif return 0;}static int snd_pcm_stream_proc_done(snd_pcm_str_t *pstr){#ifdef CONFIG_SND_DEBUG if (pstr->proc_xrun_debug_entry) { snd_info_unregister(pstr->proc_xrun_debug_entry); pstr->proc_xrun_debug_entry = NULL; }#endif if (pstr->proc_info_entry) { snd_info_unregister(pstr->proc_info_entry); pstr->proc_info_entry = NULL; } if (pstr->proc_root) { snd_info_unregister(pstr->proc_root); pstr->proc_root = NULL; } return 0;}static int snd_pcm_substream_proc_init(snd_pcm_substream_t *substream){ snd_info_entry_t *entry; snd_card_t *card; char name[16]; card = substream->pcm->card; sprintf(name, "sub%i", substream->number); if ((entry = snd_info_create_card_entry(card, name, substream->pstr->proc_root)) == NULL) return -ENOMEM; entry->mode = S_IFDIR | S_IRUGO | S_IXUGO; if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); return -ENOMEM; } substream->proc_root = entry; if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) { snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_info_read); if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); entry = NULL; } } substream->proc_info_entry = entry; if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) { snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_hw_params_read); if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); entry = NULL; } } substream->proc_hw_params_entry = entry; if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) { snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_sw_params_read); if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); entry = NULL; } } substream->proc_sw_params_entry = entry; if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) { snd_info_set_text_ops(entry, substream, 256, snd_pcm_substream_proc_status_read); if (snd_info_register(entry) < 0) { snd_info_free_entry(entry); entry = NULL; } } substream->proc_status_entry = entry; return 0;} static int snd_pcm_substream_proc_done(snd_pcm_substream_t *substream){ if (substream->proc_info_entry) { snd_info_unregister(substream->proc_info_entry); substream->proc_info_entry = NULL; } if (substream->proc_hw_params_entry) { snd_info_unregister(substream->proc_hw_params_entry); substream->proc_hw_params_entry = NULL; } if (substream->proc_sw_params_entry) { snd_info_unregister(substream->proc_sw_params_entry); substream->proc_sw_params_entry = NULL; } if (substream->proc_status_entry) { snd_info_unregister(substream->proc_status_entry); substream->proc_status_entry = NULL; } if (substream->proc_root) { snd_info_unregister(substream->proc_root); substream->proc_root = NULL; } return 0;}/** * snd_pcm_new_stream - create a new PCM stream * @pcm: the pcm instance * @stream: the stream direction, SNDRV_PCM_STREAM_XXX * @substream_count: the number of substreams * * Creates a new stream for the pcm. * The corresponding stream on the pcm must have been empty before * calling this, i.e. zero must be given to the argument of * snd_pcm_new(). * * Returns zero if successful, or a negative error code on failure. */int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count){ int idx, err; snd_pcm_str_t *pstr = &pcm->streams[stream]; snd_pcm_substream_t *substream, *prev;#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) init_MUTEX(&pstr->oss.setup_mutex);#endif pstr->stream = stream; pstr->pcm = pcm; pstr->substream_count = substream_count; pstr->reg = &snd_pcm_reg[stream]; if (substream_count > 0) { err = snd_pcm_stream_proc_init(pstr); if (err < 0) return err; } prev = NULL; for (idx = 0, prev = NULL; idx < substream_count; idx++) { substream = kcalloc(1, sizeof(*substream), GFP_KERNEL); if (substream == NULL) return -ENOMEM; substream->pcm = pcm; substream->pstr = pstr; substream->number = idx; substream->stream = stream; sprintf(substream->name, "subdevice #%i", idx); substream->buffer_bytes_max = UINT_MAX; if (prev == NULL) pstr->substream = substream; else prev->next = substream; err = snd_pcm_substream_proc_init(substream); if (err < 0) { kfree(substream); return err; } substream->group = &substream->self_group; spin_lock_init(&substream->self_group.lock); INIT_LIST_HEAD(&substream->self_group.substreams); list_add_tail(&substream->link_list, &substream->self_group.substreams); spin_lock_init(&substream->timer_lock); prev = substream; } return 0;} /** * snd_pcm_new - create a new PCM instance * @card: the card instance * @id: the id string * @device: the device index (zero based) * @playback_count: the number of substreams for playback * @capture_count: the number of substreams for capture * @rpcm: the pointer to store the new pcm instance * * Creates a new PCM instance. * * The pcm operators have to be set afterwards to the new instance * via snd_pcm_set_ops(). * * Returns zero if successful, or a negative error code on failure. */int snd_pcm_new(snd_card_t * card, char *id, int device, int playback_count, int capture_count, snd_pcm_t ** rpcm){ snd_pcm_t *pcm; int err; static snd_device_ops_t ops = { .dev_free = snd_pcm_dev_free, .dev_register = snd_pcm_dev_register, .dev_disconnect = snd_pcm_dev_disconnect, .dev_unregister = snd_pcm_dev_unregister }; snd_assert(rpcm != NULL, return -EINVAL); *rpcm = NULL; snd_assert(card != NULL, return -ENXIO); pcm = kcalloc(1, sizeof(*pcm), GFP_KERNEL); if (pcm == NULL) return -ENOMEM; pcm->card = card; pcm->device = device; if (id) { strlcpy(pcm->id, id, sizeof(pcm->id)); } if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) { snd_pcm_free(pcm); return err; } if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count)) < 0) { snd_pcm_free(pcm); return err; } init_MUTEX(&pcm->open_mutex); init_waitqueue_head(&pcm->open_wait); if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) { snd_pcm_free(pcm); return err; } *rpcm = pcm; return 0;}static void snd_pcm_free_stream(snd_pcm_str_t * pstr){ snd_pcm_substream_t *substream, *substream_next;#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) snd_pcm_oss_setup_t *setup, *setupn;#endif substream = pstr->substream; while (substream) { substream_next = substream->next; snd_pcm_substream_proc_done(substream); kfree(substream); substream = substream_next; } snd_pcm_stream_proc_done(pstr);#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) for (setup = pstr->oss.setup_list; setup; setup = setupn) { setupn = setup->next; kfree(setup->task_name); kfree(setup); }#endif}static int snd_pcm_free(snd_pcm_t *pcm){ snd_assert(pcm != NULL, return -ENXIO); if (pcm->private_free) pcm->private_free(pcm); snd_pcm_lib_preallocate_free_for_all(pcm); snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]); snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_CAPTURE]); kfree(pcm); return 0;}static int snd_pcm_dev_free(snd_device_t *device){ snd_pcm_t *pcm = device->device_data; return snd_pcm_free(pcm);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -