From: Abramo Bagnara Date: Fri, 19 Jan 2001 13:10:50 +0000 (+0000) Subject: Added support for hw_free in alsa-lib X-Git-Tag: android-x86-9.0-r1~3070 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=f12a252f2055f9dc3c006cf7a6a1f63135fd4f6b;p=android-x86%2Fexternal-alsa-lib.git Added support for hw_free in alsa-lib --- diff --git a/aserver/aserver.c b/aserver/aserver.c index ac90cefd..8dc55550 100644 --- a/aserver/aserver.c +++ b/aserver/aserver.c @@ -388,6 +388,9 @@ int pcm_shm_cmd(client_t *client) case SND_PCM_IOCTL_HW_PARAMS: ctrl->result = snd_pcm_hw_params(pcm, (snd_pcm_hw_params_t *) &ctrl->u.hw_params); break; + case SND_PCM_IOCTL_HW_FREE: + ctrl->result = snd_pcm_hw_free(pcm); + break; case SND_PCM_IOCTL_SW_PARAMS: ctrl->result = snd_pcm_sw_params(pcm, (snd_pcm_sw_params_t *) &ctrl->u.sw_params); break; diff --git a/include/pcm.h b/include/pcm.h index 96849fee..99809d1d 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -60,6 +60,7 @@ int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid); int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info); int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); +int snd_pcm_hw_free(snd_pcm_t *pcm); int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status); int snd_pcm_prepare(snd_pcm_t *pcm); diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 9457511e..9e8d5bed 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -55,9 +55,8 @@ int snd_pcm_close(snd_pcm_t *pcm) snd_pcm_drop(pcm); else snd_pcm_drain(pcm); - } - if (pcm->mmap_channels) { - if ((err = snd_pcm_munmap(pcm)) < 0) + err = snd_pcm_hw_free(pcm); + if (err < 0) ret = err; } if ((err = pcm->ops->close(pcm->op_arg)) < 0) diff --git a/src/pcm/pcm_adpcm.c b/src/pcm/pcm_adpcm.c index 6928b677..bdbdb660 100644 --- a/src/pcm/pcm_adpcm.c +++ b/src/pcm/pcm_adpcm.c @@ -317,18 +317,6 @@ static void adpcm_encode(const snd_pcm_channel_area_t *src_areas, } } -static int snd_pcm_adpcm_close(snd_pcm_t *pcm) -{ - snd_pcm_adpcm_t *adpcm = pcm->private; - int err = 0; - if (adpcm->plug.close_slave) - err = snd_pcm_close(adpcm->plug.slave); - if (adpcm->states) - free(adpcm->states); - free(adpcm); - return 0; -} - static int snd_pcm_adpcm_hw_refine_cprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { snd_pcm_adpcm_t *adpcm = pcm->private; @@ -449,12 +437,21 @@ static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) adpcm->func = adpcm_encode; } } - if (adpcm->states) - free(adpcm->states); + assert(!adpcm->states); adpcm->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS, 0) * sizeof(*adpcm->states)); return 0; } +static int snd_pcm_adpcm_hw_free(snd_pcm_t *pcm) +{ + snd_pcm_adpcm_t *adpcm = pcm->private; + if (adpcm->states) { + free(adpcm->states); + adpcm->states = 0; + } + return snd_pcm_hw_free(adpcm->plug.slave); +} + static int snd_pcm_adpcm_init(snd_pcm_t *pcm) { snd_pcm_adpcm_t *adpcm = pcm->private; @@ -550,11 +547,12 @@ static void snd_pcm_adpcm_dump(snd_pcm_t *pcm, snd_output_t *out) } snd_pcm_ops_t snd_pcm_adpcm_ops = { - close: snd_pcm_adpcm_close, + close: snd_pcm_plugin_close, card: snd_pcm_plugin_card, info: snd_pcm_plugin_info, hw_refine: snd_pcm_adpcm_hw_refine, hw_params: snd_pcm_adpcm_hw_params, + hw_free: snd_pcm_adpcm_hw_free, sw_params: snd_pcm_plugin_sw_params, channel_info: snd_pcm_plugin_channel_info, dump: snd_pcm_adpcm_dump, diff --git a/src/pcm/pcm_alaw.c b/src/pcm/pcm_alaw.c index c9756d80..66444838 100644 --- a/src/pcm/pcm_alaw.c +++ b/src/pcm/pcm_alaw.c @@ -422,6 +422,7 @@ snd_pcm_ops_t snd_pcm_alaw_ops = { info: snd_pcm_plugin_info, hw_refine: snd_pcm_alaw_hw_refine, hw_params: snd_pcm_alaw_hw_params, + hw_free: snd_pcm_plugin_hw_free, sw_params: snd_pcm_plugin_sw_params, channel_info: snd_pcm_plugin_channel_info, dump: snd_pcm_alaw_dump, diff --git a/src/pcm/pcm_copy.c b/src/pcm/pcm_copy.c index 9072b530..d5c5e9a9 100644 --- a/src/pcm/pcm_copy.c +++ b/src/pcm/pcm_copy.c @@ -179,6 +179,7 @@ snd_pcm_ops_t snd_pcm_copy_ops = { info: snd_pcm_plugin_info, hw_refine: snd_pcm_copy_hw_refine, hw_params: snd_pcm_copy_hw_params, + hw_free: snd_pcm_plugin_hw_free, sw_params: snd_pcm_plugin_sw_params, channel_info: snd_pcm_plugin_channel_info, dump: snd_pcm_copy_dump, diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c index d5cb5885..a080f7f8 100644 --- a/src/pcm/pcm_file.c +++ b/src/pcm/pcm_file.c @@ -105,12 +105,6 @@ static int snd_pcm_file_close(snd_pcm_t *pcm) free(file->fname); close(file->fd); } - if (file->wbuf) { - free(file->wbuf); - free(file->wbuf_areas); - file->wbuf = 0; - file->wbuf_areas = 0; - } free(file); return 0; } @@ -322,13 +316,10 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) int err = snd_pcm_hw_params(slave, params); if (err < 0) return err; - if (file->wbuf) { - free(file->wbuf); - free(file->wbuf_areas); - } file->buffer_bytes = snd_pcm_frames_to_bytes(slave, slave->buffer_size); file->wbuf_size = slave->buffer_size * 2; file->wbuf_size_bytes = snd_pcm_frames_to_bytes(slave, file->wbuf_size); + assert(!file->wbuf); file->wbuf = malloc(file->wbuf_size_bytes); file->wbuf_areas = malloc(sizeof(*file->wbuf_areas) * slave->channels); file->appl_ptr = file->file_ptr_bytes = 0; @@ -341,6 +332,18 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) return 0; } +static int snd_pcm_file_hw_free(snd_pcm_t *pcm) +{ + snd_pcm_file_t *file = pcm->private; + if (file->wbuf) { + free(file->wbuf); + free(file->wbuf_areas); + file->wbuf = 0; + file->wbuf_areas = 0; + } + return snd_pcm_hw_free(file->slave); +} + static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params) { snd_pcm_file_t *file = pcm->private; @@ -378,6 +381,7 @@ snd_pcm_ops_t snd_pcm_file_ops = { info: snd_pcm_file_info, hw_refine: snd_pcm_file_hw_refine, hw_params: snd_pcm_file_hw_params, + hw_free: snd_pcm_file_hw_free, sw_params: snd_pcm_file_sw_params, channel_info: snd_pcm_file_channel_info, dump: snd_pcm_file_dump, diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index 51701127..55b5c85b 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -148,6 +148,17 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) return 0; } +static int snd_pcm_hw_hw_free(snd_pcm_t *pcm) +{ + snd_pcm_hw_t *hw = pcm->private; + int fd = hw->fd; + if (ioctl(fd, SND_PCM_IOCTL_HW_FREE) < 0) { + SYSERR("SND_PCM_IOCTL_HW_FREE failed"); + return -errno; + } + return 0; +} + static int snd_pcm_hw_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params) { snd_pcm_hw_t *hw = pcm->private; @@ -508,6 +519,7 @@ snd_pcm_ops_t snd_pcm_hw_ops = { info: snd_pcm_hw_info, hw_refine: snd_pcm_hw_hw_refine, hw_params: snd_pcm_hw_hw_params, + hw_free: snd_pcm_hw_hw_free, sw_params: snd_pcm_hw_sw_params, channel_info: snd_pcm_hw_channel_info, dump: snd_pcm_hw_dump, diff --git a/src/pcm/pcm_linear.c b/src/pcm/pcm_linear.c index 95c09715..3731ac1a 100644 --- a/src/pcm/pcm_linear.c +++ b/src/pcm/pcm_linear.c @@ -262,6 +262,7 @@ snd_pcm_ops_t snd_pcm_linear_ops = { info: snd_pcm_plugin_info, hw_refine: snd_pcm_linear_hw_refine, hw_params: snd_pcm_linear_hw_params, + hw_free: snd_pcm_plugin_hw_free, sw_params: snd_pcm_plugin_sw_params, channel_info: snd_pcm_plugin_channel_info, dump: snd_pcm_linear_dump, diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 36badaa5..c869a1d3 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -55,6 +55,7 @@ typedef struct { int (*info)(snd_pcm_t *pcm, snd_pcm_info_t *info); int (*hw_refine)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); int (*hw_params)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); + int (*hw_free)(snd_pcm_t *pcm); int (*sw_params)(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); int (*channel_info)(snd_pcm_t *pcm, snd_pcm_channel_info_t *info); void (*dump)(snd_pcm_t *pcm, snd_output_t *out); diff --git a/src/pcm/pcm_mulaw.c b/src/pcm/pcm_mulaw.c index b501e66e..3cab2b5b 100644 --- a/src/pcm/pcm_mulaw.c +++ b/src/pcm/pcm_mulaw.c @@ -437,6 +437,7 @@ snd_pcm_ops_t snd_pcm_mulaw_ops = { info: snd_pcm_plugin_info, hw_refine: snd_pcm_mulaw_hw_refine, hw_params: snd_pcm_mulaw_hw_params, + hw_free: snd_pcm_plugin_hw_free, sw_params: snd_pcm_plugin_sw_params, channel_info: snd_pcm_plugin_channel_info, dump: snd_pcm_mulaw_dump, diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index 53fbbc8d..121014e3 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -286,6 +286,20 @@ static int snd_pcm_multi_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) return 0; } +static int snd_pcm_multi_hw_free(snd_pcm_t *pcm) +{ + snd_pcm_multi_t *multi = pcm->private; + unsigned int i; + int err = 0; + for (i = 0; i < multi->slaves_count; ++i) { + snd_pcm_t *slave = multi->slaves[i].pcm; + int e = snd_pcm_hw_free(slave); + if (e < 0) + err = e; + } + return err; +} + static int snd_pcm_multi_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params) { snd_pcm_multi_t *multi = pcm->private; @@ -468,6 +482,7 @@ snd_pcm_ops_t snd_pcm_multi_ops = { info: snd_pcm_multi_info, hw_refine: snd_pcm_multi_hw_refine, hw_params: snd_pcm_multi_hw_params, + hw_free: snd_pcm_multi_hw_free, sw_params: snd_pcm_multi_sw_params, channel_info: snd_pcm_multi_channel_info, dump: snd_pcm_multi_dump, diff --git a/src/pcm/pcm_null.c b/src/pcm/pcm_null.c index 1f46659c..eb16dea4 100644 --- a/src/pcm/pcm_null.c +++ b/src/pcm/pcm_null.c @@ -241,6 +241,11 @@ static int snd_pcm_null_hw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_pa return 0; } +static int snd_pcm_null_hw_free(snd_pcm_t *pcm ATTRIBUTE_UNUSED) +{ + return 0; +} + static int snd_pcm_null_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t * params ATTRIBUTE_UNUSED) { return 0; @@ -286,6 +291,7 @@ snd_pcm_ops_t snd_pcm_null_ops = { info: snd_pcm_null_info, hw_refine: snd_pcm_null_hw_refine, hw_params: snd_pcm_null_hw_params, + hw_free: snd_pcm_null_hw_free, sw_params: snd_pcm_null_sw_params, channel_info: snd_pcm_null_channel_info, dump: snd_pcm_null_dump, diff --git a/src/pcm/pcm_params.c b/src/pcm/pcm_params.c index b2fe8a0d..6f1151e7 100644 --- a/src/pcm/pcm_params.c +++ b/src/pcm/pcm_params.c @@ -2274,14 +2274,14 @@ int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) if (err < 0) return err; snd_pcm_hw_params_choose(pcm, params); - if (pcm->mmap_channels) { - err = snd_pcm_munmap(pcm); + if (pcm->setup) { + err = snd_pcm_hw_free(pcm); if (err < 0) - return err; + return 0; } err = pcm->ops->hw_params(pcm->op_arg, params); if (err < 0) - goto _mmap; + return err; pcm->setup = 1; pcm->access = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_ACCESS, 0); @@ -2314,22 +2314,32 @@ int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) err = snd_pcm_sw_params(pcm, &sw); assert(err >= 0); - _mmap: - if (pcm->setup && - (pcm->mmap_rw || - (pcm->access == SND_PCM_ACCESS_MMAP_INTERLEAVED || - pcm->access == SND_PCM_ACCESS_MMAP_NONINTERLEAVED || - pcm->access == SND_PCM_ACCESS_MMAP_COMPLEX))) { - int err; + if (pcm->mmap_rw || + pcm->access == SND_PCM_ACCESS_MMAP_INTERLEAVED || + pcm->access == SND_PCM_ACCESS_MMAP_NONINTERLEAVED || + pcm->access == SND_PCM_ACCESS_MMAP_COMPLEX) { err = snd_pcm_mmap(pcm); - if (err < 0) - return err; } if (err >= 0) err = snd_pcm_prepare(pcm); return err; } +int snd_pcm_hw_free(snd_pcm_t *pcm) +{ + int err; + assert(pcm->setup); + assert(snd_pcm_state(pcm) <= SND_PCM_STATE_PREPARED); + if (pcm->mmap_channels) { + err = snd_pcm_munmap(pcm); + if (err < 0) + return err; + } + err = pcm->ops->hw_free(pcm->op_arg); + pcm->setup = 0; + return err; +} + int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params) { int err; diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index acd1f76e..34bb36e5 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -37,11 +37,7 @@ static int snd_pcm_plug_close(snd_pcm_t *pcm) int err, result = 0; if (plug->ttable) free(plug->ttable); - if (plug->slave != plug->req_slave) { - err = snd_pcm_close(plug->slave); - if (err < 0) - result = err; - } + assert(plug->slave == plug->req_slave); if (plug->close_slave) { err = snd_pcm_close(plug->req_slave); if (err < 0) @@ -587,6 +583,15 @@ static int snd_pcm_plug_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) return 0; } +static int snd_pcm_plug_hw_free(snd_pcm_t *pcm) +{ + snd_pcm_plug_t *plug = pcm->private; + snd_pcm_t *slave = plug->slave; + int err = snd_pcm_hw_free(slave); + snd_pcm_plug_clear(pcm); + return err; +} + static int snd_pcm_plug_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params) { snd_pcm_plug_t *plug = pcm->private; @@ -639,6 +644,7 @@ snd_pcm_ops_t snd_pcm_plug_ops = { info: snd_pcm_plug_info, hw_refine: snd_pcm_plug_hw_refine, hw_params: snd_pcm_plug_hw_params, + hw_free: snd_pcm_plug_hw_free, sw_params: snd_pcm_plug_sw_params, channel_info: snd_pcm_plug_channel_info, dump: snd_pcm_plug_dump, diff --git a/src/pcm/pcm_plugin.c b/src/pcm/pcm_plugin.c index 78eb5583..87415bbf 100644 --- a/src/pcm/pcm_plugin.c +++ b/src/pcm/pcm_plugin.c @@ -58,6 +58,12 @@ int snd_pcm_plugin_info(snd_pcm_t *pcm, snd_pcm_info_t * info) return snd_pcm_info(plugin->slave, info); } +int snd_pcm_plugin_hw_free(snd_pcm_t *pcm) +{ + snd_pcm_plugin_t *plugin = pcm->private; + return snd_pcm_hw_free(plugin->slave); +} + int snd_pcm_plugin_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params) { snd_pcm_plugin_t *plugin = pcm->private; diff --git a/src/pcm/pcm_plugin.h b/src/pcm/pcm_plugin.h index 62f75ddc..eca3b2f5 100644 --- a/src/pcm/pcm_plugin.h +++ b/src/pcm/pcm_plugin.h @@ -36,6 +36,7 @@ int snd_pcm_plugin_card(snd_pcm_t *pcm); int snd_pcm_plugin_nonblock(snd_pcm_t *pcm, int nonblock); int snd_pcm_plugin_async(snd_pcm_t *pcm, int sig, pid_t pid); int snd_pcm_plugin_info(snd_pcm_t *pcm, snd_pcm_info_t * info); +int snd_pcm_plugin_hw_free(snd_pcm_t *pcm); int snd_pcm_plugin_sw_refine(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); int snd_pcm_plugin_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); int snd_pcm_plugin_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info); diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c index 780f2b4b..c0186786 100644 --- a/src/pcm/pcm_rate.c +++ b/src/pcm/pcm_rate.c @@ -222,18 +222,6 @@ static snd_pcm_uframes_t resample_shrink(const snd_pcm_channel_area_t *src_areas return src_frames1; } -static int snd_pcm_rate_close(snd_pcm_t *pcm) -{ - snd_pcm_rate_t *rate = pcm->private; - int err = 0; - if (rate->plug.close_slave) - err = snd_pcm_close(rate->plug.slave); - if (rate->states) - free(rate->states); - free(rate); - return 0; -} - static int snd_pcm_rate_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params) { int err; @@ -390,12 +378,21 @@ static int snd_pcm_rate_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) /* pitch is get_increment */ } rate->pitch = (((u_int64_t)dst_rate * DIV) + src_rate / 2) / src_rate; - if (rate->states) - free(rate->states); + assert(!rate->states); rate->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS, 0) * sizeof(*rate->states)); return 0; } +static int snd_pcm_rate_hw_free(snd_pcm_t *pcm) +{ + snd_pcm_rate_t *rate = pcm->private; + if (rate->states) { + free(rate->states); + rate->states = 0; + } + return snd_pcm_hw_free(rate->plug.slave); +} + static int snd_pcm_rate_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params) { snd_pcm_rate_t *rate = pcm->private; @@ -577,11 +574,12 @@ static void snd_pcm_rate_dump(snd_pcm_t *pcm, snd_output_t *out) } snd_pcm_ops_t snd_pcm_rate_ops = { - close: snd_pcm_rate_close, + close: snd_pcm_plugin_close, card: snd_pcm_plugin_card, info: snd_pcm_plugin_info, hw_refine: snd_pcm_rate_hw_refine, hw_params: snd_pcm_rate_hw_params, + hw_free: snd_pcm_rate_hw_free, sw_params: snd_pcm_rate_sw_params, channel_info: snd_pcm_plugin_channel_info, dump: snd_pcm_rate_dump, diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c index afe6ce5f..dfe2a974 100644 --- a/src/pcm/pcm_route.c +++ b/src/pcm/pcm_route.c @@ -678,6 +678,7 @@ snd_pcm_ops_t snd_pcm_route_ops = { info: snd_pcm_plugin_info, hw_refine: snd_pcm_route_hw_refine, hw_params: snd_pcm_route_hw_params, + hw_free: snd_pcm_plugin_hw_free, sw_params: snd_pcm_plugin_sw_params, channel_info: snd_pcm_plugin_channel_info, dump: snd_pcm_route_dump, diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c index 57c3e573..194d000a 100644 --- a/src/pcm/pcm_share.c +++ b/src/pcm/pcm_share.c @@ -649,6 +649,20 @@ static int snd_pcm_share_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) return err; } +static int snd_pcm_share_hw_free(snd_pcm_t *pcm) +{ + snd_pcm_share_t *share = pcm->private; + snd_pcm_share_slave_t *slave = share->slave; + int err = 0; + Pthread_mutex_lock(&slave->mutex); + slave->setup_count--; + if (slave->setup_count == 0) + err = snd_pcm_hw_free(slave->pcm); + share->state = SND_PCM_STATE_OPEN; + Pthread_mutex_unlock(&slave->mutex); + return err; +} + static int snd_pcm_share_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED) { return 0; @@ -1078,8 +1092,6 @@ static int snd_pcm_share_close(snd_pcm_t *pcm) int err = 0; Pthread_mutex_lock(&slaves_mutex); Pthread_mutex_lock(&slave->mutex); - if (pcm->setup) - slave->setup_count--; slave->open_count--; if (slave->open_count == 0) { err = snd_pcm_close(slave->pcm); @@ -1137,6 +1149,7 @@ snd_pcm_ops_t snd_pcm_share_ops = { info: snd_pcm_share_info, hw_refine: snd_pcm_share_hw_refine, hw_params: snd_pcm_share_hw_params, + hw_free: snd_pcm_share_hw_free, sw_params: snd_pcm_share_sw_params, channel_info: snd_pcm_share_channel_info, dump: snd_pcm_share_dump, diff --git a/src/pcm/pcm_shm.c b/src/pcm/pcm_shm.c index b895bde4..b478ec7c 100644 --- a/src/pcm/pcm_shm.c +++ b/src/pcm/pcm_shm.c @@ -253,6 +253,14 @@ static int snd_pcm_shm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) snd_pcm_shm_hw_params_slave); } +static int snd_pcm_shm_hw_free(snd_pcm_t *pcm) +{ + snd_pcm_shm_t *shm = pcm->private; + volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl; + ctrl->cmd = SND_PCM_IOCTL_HW_FREE; + return snd_pcm_shm_action(pcm); +} + static int snd_pcm_shm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params) { snd_pcm_shm_t *shm = pcm->private; @@ -487,6 +495,7 @@ snd_pcm_ops_t snd_pcm_shm_ops = { info: snd_pcm_shm_info, hw_refine: snd_pcm_shm_hw_refine, hw_params: snd_pcm_shm_hw_params, + hw_free: snd_pcm_shm_hw_free, sw_params: snd_pcm_shm_sw_params, channel_info: snd_pcm_shm_channel_info, dump: snd_pcm_shm_dump,