static int capture_prepare_params(struct gaudio_snd_dev *snd) { struct snd_pcm_substream *substream = snd->substream; struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_hw_params *params; struct snd_pcm_sw_params *swparams; unsigned long period_size; unsigned long buffer_size; snd_pcm_sframes_t result = 0; snd->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED; snd->format = SNDRV_PCM_FORMAT_S16_LE; snd->channels = 1; snd->rate = 8000; params = kzalloc(sizeof(*params), GFP_KERNEL); if (!params) { pr_err("Failed to allocate hw params"); return -ENOMEM; } _snd_pcm_hw_params_any(params); _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS, snd->access, 0); _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT, snd->format, 0); _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS, snd->channels, 0); _snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE, snd->rate, 0); result = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); if (result < 0) pr_err("SNDRV_PCM_IOCTL_DROP failed: %d\n", (int)result); result = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, params); if (result < 0) { pr_err("SNDRV_PCM_IOCTL_HW_PARAMS failed: %d\n", (int)result); kfree(params); return result; } result = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL); if (result < 0) pr_err("Preparing capture failed: %d\n", (int)result); snd->access = params_access(params); snd->format = params_format(params); snd->channels = params_channels(params); snd->rate = params_rate(params); runtime->frame_bits = snd_pcm_format_physical_width(runtime->format); swparams = kzalloc(sizeof(*swparams), GFP_KERNEL); if (!swparams) { pr_err("Failed to allocate sw params"); kfree(params); return -ENOMEM; } buffer_size = pcm_buffer_size(params); period_size = pcm_period_size(params); swparams->avail_min = period_size/2; swparams->xfer_align = period_size/2; kfree(params); swparams->tstamp_mode = SNDRV_PCM_TSTAMP_NONE; swparams->period_step = 1; swparams->start_threshold = 1; swparams->stop_threshold = INT_MAX; swparams->silence_size = 0; swparams->silence_threshold = 0; result = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_SW_PARAMS, swparams); if (result < 0) pr_err("SNDRV_PCM_IOCTL_SW_PARAMS failed: %d\n", (int)result); kfree(swparams); pr_debug("capture params: access %x, format %x, channels %d, rate %d\n", snd->access, snd->format, snd->channels, snd->rate); return result; }
static int set_params(struct pcm *pcm) { struct snd_pcm_hw_params *params; struct snd_pcm_sw_params *sparams; unsigned long periodSize, bufferSize, reqBuffSize; unsigned int periodTime, bufferTime; unsigned int requestedRate = pcm->rate; int channels = (pcm->flags & PCM_MONO) ? 1 : ((pcm->flags & PCM_5POINT1)? 6 : 2 ); params = (struct snd_pcm_hw_params*) calloc(1, sizeof(struct snd_pcm_hw_params)); if (!params) { fprintf(stderr, "Aplay:Failed to allocate ALSA hardware parameters!"); return -ENOMEM; } param_init(params); param_set_mask(params, SNDRV_PCM_HW_PARAM_ACCESS, (pcm->flags & PCM_MMAP)? SNDRV_PCM_ACCESS_MMAP_INTERLEAVED : SNDRV_PCM_ACCESS_RW_INTERLEAVED); param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, pcm->format); param_set_mask(params, SNDRV_PCM_HW_PARAM_SUBFORMAT, SNDRV_PCM_SUBFORMAT_STD); if (period) param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, period); else param_set_min(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 10); param_set_int(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 16); param_set_int(params, SNDRV_PCM_HW_PARAM_FRAME_BITS, pcm->channels * 16); param_set_int(params, SNDRV_PCM_HW_PARAM_CHANNELS, pcm->channels); param_set_int(params, SNDRV_PCM_HW_PARAM_RATE, pcm->rate); param_set_hw_refine(pcm, params); if (param_set_hw_params(pcm, params)) { fprintf(stderr, "Aplay:cannot set hw params\n"); return -errno; } if (debug) param_dump(params); pcm->buffer_size = pcm_buffer_size(params); pcm->period_size = pcm_period_size(params); pcm->period_cnt = pcm->buffer_size/pcm->period_size; if (debug) { fprintf (stderr,"period_cnt = %d\n", pcm->period_cnt); fprintf (stderr,"period_size = %d\n", pcm->period_size); fprintf (stderr,"buffer_size = %d\n", pcm->buffer_size); } sparams = (struct snd_pcm_sw_params*) calloc(1, sizeof(struct snd_pcm_sw_params)); if (!sparams) { fprintf(stderr, "Aplay:Failed to allocate ALSA software parameters!\n"); return -ENOMEM; } // Get the current software parameters sparams->tstamp_mode = SNDRV_PCM_TSTAMP_NONE; sparams->period_step = 1; sparams->avail_min = pcm->period_size/(channels * 2) ; sparams->start_threshold = pcm->period_size/(channels * 2) ; sparams->stop_threshold = pcm->buffer_size ; sparams->xfer_align = pcm->period_size/(channels * 2) ; /* needed for old kernels */ sparams->silence_size = 0; sparams->silence_threshold = 0; if (param_set_sw_params(pcm, sparams)) { fprintf(stderr, "Aplay:cannot set sw params"); return -errno; } if (debug) { fprintf (stderr,"sparams->avail_min= %lu\n", sparams->avail_min); fprintf (stderr," sparams->start_threshold= %lu\n", sparams->start_threshold); fprintf (stderr," sparams->stop_threshold= %lu\n", sparams->stop_threshold); fprintf (stderr," sparams->xfer_align= %lu\n", sparams->xfer_align); fprintf (stderr," sparams->boundary= %lu\n", sparams->boundary); } return 0; }