int pa__init(pa_module*m) { pa_modargs *ma = NULL; int ret = -1; int32_t fd = -1; char x = 1; pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs)) || pa_modargs_get_value_s32(ma, "fd", &fd) < 0 || fd < 0) { pa_log("Failed to parse module arguments"); goto finish; } if (pa_loop_write(fd, &x, sizeof(x), NULL) != sizeof(x)) pa_log_warn("write(%u, 1, 1) failed: %s", fd, pa_cstrerror(errno)); pa_assert_se(pa_close(fd) == 0); pa_module_unload_request(m, true); ret = 0; finish: if (ma) pa_modargs_free(ma); return ret; }
int pa__init(pa_module*m) { pa_iochannel *io; pa_modargs *ma; int32_t fd = -1; int r = -1; pa_native_options *options = NULL; pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments."); goto finish; } if (pa_modargs_get_value_s32(ma, "fd", &fd) < 0 || fd < 0) { pa_log("Invalid file descriptor."); goto finish; } m->userdata = pa_native_protocol_get(m->core); io = pa_iochannel_new(m->core->mainloop, fd, fd); options = pa_native_options_new(); options->module = m; options->auth_anonymous = true; pa_native_protocol_connect(m->userdata, io, options); r = 0; finish: if (ma) pa_modargs_free(ma); if (options) pa_native_options_unref(options); return r; }
static pa_bool_t pa_speex_ec_preprocessor_init(pa_echo_canceller *ec, pa_sample_spec *source_ss, uint32_t nframes, pa_modargs *ma) { pa_bool_t agc; pa_bool_t denoise; pa_bool_t echo_suppress; int32_t echo_suppress_attenuation; int32_t echo_suppress_attenuation_active; agc = DEFAULT_AGC_ENABLED; if (pa_modargs_get_value_boolean(ma, "agc", &agc) < 0) { pa_log("Failed to parse agc value"); goto fail; } denoise = DEFAULT_DENOISE_ENABLED; if (pa_modargs_get_value_boolean(ma, "denoise", &denoise) < 0) { pa_log("Failed to parse denoise value"); goto fail; } echo_suppress = DEFAULT_ECHO_SUPPRESS_ENABLED; if (pa_modargs_get_value_boolean(ma, "echo_suppress", &echo_suppress) < 0) { pa_log("Failed to parse echo_suppress value"); goto fail; } echo_suppress_attenuation = DEFAULT_ECHO_SUPPRESS_ATTENUATION; if (pa_modargs_get_value_s32(ma, "echo_suppress_attenuation", &echo_suppress_attenuation) < 0) { pa_log("Failed to parse echo_suppress_attenuation value"); goto fail; } if (echo_suppress_attenuation > 0) { pa_log("echo_suppress_attenuation should be a negative dB value"); goto fail; } echo_suppress_attenuation_active = DEFAULT_ECHO_SUPPRESS_ATTENUATION; if (pa_modargs_get_value_s32(ma, "echo_suppress_attenuation_active", &echo_suppress_attenuation_active) < 0) { pa_log("Failed to parse echo_suppress_attenuation_active value"); goto fail; } if (echo_suppress_attenuation_active > 0) { pa_log("echo_suppress_attenuation_active should be a negative dB value"); goto fail; } if (agc || denoise || echo_suppress) { spx_int32_t tmp; if (source_ss->channels != 1) { pa_log("AGC, denoising and echo suppression only work with channels=1"); goto fail; } ec->params.priv.speex.pp_state = speex_preprocess_state_init(nframes, source_ss->rate); tmp = agc; speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_AGC, &tmp); tmp = denoise; speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_DENOISE, &tmp); if (echo_suppress) { if (echo_suppress_attenuation) speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS, &echo_suppress_attenuation); if (echo_suppress_attenuation_active) { speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE, &echo_suppress_attenuation_active); } speex_preprocess_ctl(ec->params.priv.speex.pp_state, SPEEX_PREPROCESS_SET_ECHO_STATE, ec->params.priv.speex.state); } pa_log_info("Loaded speex preprocessor with params: agc=%s, denoise=%s, echo_suppress=%s", pa_yes_no(agc), pa_yes_no(denoise), pa_yes_no(echo_suppress)); } else pa_log_info("All preprocessing options are disabled"); return TRUE; fail: return FALSE; }
int pa__init(pa_module*m) { struct audio_buf_info info; struct userdata *u = NULL; const char *dev; int fd = -1; int nfrags, orig_frag_size, frag_size; int mode, caps; pa_bool_t record = TRUE, playback = TRUE, use_mmap = TRUE; pa_sample_spec ss; pa_channel_map map; pa_modargs *ma = NULL; char hwdesc[64]; const char *name; pa_bool_t namereg_fail; pa_sink_new_data sink_new_data; pa_source_new_data source_new_data; pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments."); goto fail; } if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) { pa_log("record= and playback= expect boolean argument."); goto fail; } if (!playback && !record) { pa_log("Neither playback nor record enabled for device."); goto fail; } mode = (playback && record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); ss = m->core->default_sample_spec; map = m->core->default_channel_map; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_OSS) < 0) { pa_log("Failed to parse sample specification or channel map"); goto fail; } nfrags = (int) m->core->default_n_fragments; frag_size = (int) pa_usec_to_bytes(m->core->default_fragment_size_msec*1000, &ss); if (frag_size <= 0) frag_size = (int) pa_frame_size(&ss); if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0) { pa_log("Failed to parse fragments arguments"); goto fail; } if (pa_modargs_get_value_boolean(ma, "mmap", &use_mmap) < 0) { pa_log("Failed to parse mmap argument."); goto fail; } if ((fd = pa_oss_open(dev = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, &caps)) < 0) goto fail; if (use_mmap && (!(caps & DSP_CAP_MMAP) || !(caps & DSP_CAP_TRIGGER))) { pa_log_info("OSS device not mmap capable, falling back to UNIX read/write mode."); use_mmap = FALSE; } if (use_mmap && mode == O_WRONLY) { pa_log_info("Device opened for playback only, cannot do memory mapping, falling back to UNIX write() mode."); use_mmap = FALSE; } if (pa_oss_get_hw_description(dev, hwdesc, sizeof(hwdesc)) >= 0) pa_log_info("Hardware name is '%s'.", hwdesc); else hwdesc[0] = 0; pa_log_info("Device opened in %s mode.", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); orig_frag_size = frag_size; if (nfrags >= 2 && frag_size >= 1) if (pa_oss_set_fragments(fd, nfrags, frag_size) < 0) goto fail; if (pa_oss_auto_format(fd, &ss) < 0) goto fail; if (ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &frag_size) < 0) { pa_log("SNDCTL_DSP_GETBLKSIZE: %s", pa_cstrerror(errno)); goto fail; } pa_assert(frag_size > 0); u = pa_xnew0(struct userdata, 1); u->core = m->core; u->module = m; m->userdata = u; u->fd = fd; u->mixer_fd = -1; u->mixer_devmask = 0; u->use_getospace = u->use_getispace = TRUE; u->use_getodelay = TRUE; u->mode = mode; u->frame_size = pa_frame_size(&ss); u->device_name = pa_xstrdup(dev); u->in_nfrags = u->out_nfrags = (uint32_t) (u->nfrags = nfrags); u->out_fragment_size = u->in_fragment_size = (uint32_t) (u->frag_size = frag_size); u->orig_frag_size = orig_frag_size; u->use_mmap = use_mmap; u->rtpoll = pa_rtpoll_new(); pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll); u->rtpoll_item = NULL; build_pollfd(u); if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) >= 0) { pa_log_info("Input -- %u fragments of size %u.", info.fragstotal, info.fragsize); u->in_fragment_size = (uint32_t) info.fragsize; u->in_nfrags = (uint32_t) info.fragstotal; u->use_getispace = TRUE; } if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) >= 0) { pa_log_info("Output -- %u fragments of size %u.", info.fragstotal, info.fragsize); u->out_fragment_size = (uint32_t) info.fragsize; u->out_nfrags = (uint32_t) info.fragstotal; u->use_getospace = TRUE; } u->in_hwbuf_size = u->in_nfrags * u->in_fragment_size; u->out_hwbuf_size = u->out_nfrags * u->out_fragment_size; if (mode != O_WRONLY) { char *name_buf = NULL; if (use_mmap) { if ((u->in_mmap = mmap(NULL, u->in_hwbuf_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { pa_log_warn("mmap(PROT_READ) failed, reverting to non-mmap mode: %s", pa_cstrerror(errno)); use_mmap = u->use_mmap = FALSE; u->in_mmap = NULL; } else pa_log_debug("Successfully mmap()ed input buffer."); } if ((name = pa_modargs_get_value(ma, "source_name", NULL))) namereg_fail = TRUE; else { name = name_buf = pa_sprintf_malloc("oss_input.%s", pa_path_get_filename(dev)); namereg_fail = FALSE; } pa_source_new_data_init(&source_new_data); source_new_data.driver = __FILE__; source_new_data.module = m; pa_source_new_data_set_name(&source_new_data, name); source_new_data.namereg_fail = namereg_fail; pa_source_new_data_set_sample_spec(&source_new_data, &ss); pa_source_new_data_set_channel_map(&source_new_data, &map); pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_STRING, dev); pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_API, "oss"); pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_DESCRIPTION, hwdesc[0] ? hwdesc : dev); pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_ACCESS_MODE, use_mmap ? "mmap" : "serial"); pa_proplist_setf(source_new_data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) (u->in_hwbuf_size)); pa_proplist_setf(source_new_data.proplist, PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE, "%lu", (unsigned long) (u->in_fragment_size)); if (pa_modargs_get_proplist(ma, "source_properties", source_new_data.proplist, PA_UPDATE_REPLACE) < 0) { pa_log("Invalid properties"); pa_source_new_data_done(&source_new_data); goto fail; } u->source = pa_source_new(m->core, &source_new_data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY); pa_source_new_data_done(&source_new_data); pa_xfree(name_buf); if (!u->source) { pa_log("Failed to create source object"); goto fail; } u->source->parent.process_msg = source_process_msg; u->source->userdata = u; pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); pa_source_set_rtpoll(u->source, u->rtpoll); pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->in_hwbuf_size, &u->source->sample_spec)); u->source->refresh_volume = TRUE; if (use_mmap) u->in_mmap_memblocks = pa_xnew0(pa_memblock*, u->in_nfrags); }
int pa__init(pa_module *m) { struct userdata *u = NULL; const char *p; int fd = -1; int buffer_size; int mode; int record = 1, playback = 1; pa_sample_spec ss; pa_channel_map map; pa_modargs *ma = NULL; char *t; struct pollfd *pollfd; pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("failed to parse module arguments."); goto fail; } if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) { pa_log("record= and playback= expect numeric argument."); goto fail; } if (!playback && !record) { pa_log("neither playback nor record enabled for device."); goto fail; } mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0)); buffer_size = 16384; if (pa_modargs_get_value_s32(ma, "buffer_size", &buffer_size) < 0) { pa_log("failed to parse buffer size argument"); goto fail; } ss = m->core->default_sample_spec; if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { pa_log("failed to parse sample specification"); goto fail; } if ((fd = open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), mode | O_NONBLOCK)) < 0) goto fail; pa_log_info("device opened in %s mode.", mode == O_WRONLY ? "O_WRONLY" : (mode == O_RDONLY ? "O_RDONLY" : "O_RDWR")); if (pa_solaris_auto_format(fd, mode, &ss) < 0) goto fail; if (pa_solaris_set_buffer(fd, buffer_size) < 0) goto fail; u = pa_xmalloc(sizeof(struct userdata)); u->core = m->core; u->fd = fd; pa_memchunk_reset(&u->memchunk); /* We use this to get a reasonable chunk size */ u->page_size = PA_PAGE_SIZE; u->frame_size = pa_frame_size(&ss); u->buffer_size = buffer_size; u->written_bytes = 0; u->read_bytes = 0; u->module = m; m->userdata = u; pa_thread_mq_init(&u->thread_mq, m->core->mainloop); u->rtpoll = pa_rtpoll_new(); pa_rtpoll_item_new_asyncmsgq(u->rtpoll, PA_RTPOLL_EARLY, u->thread_mq.inq); pa_rtpoll_set_timer_periodic(u->rtpoll, pa_bytes_to_usec(u->buffer_size / 10, &ss)); u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); pollfd->fd = fd; pollfd->events = 0; pollfd->revents = 0; if (mode != O_WRONLY) { u->source = pa_source_new(m->core, __FILE__, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME), 0, &ss, &map); pa_assert(u->source); u->source->userdata = u; u->source->parent.process_msg = source_process_msg; pa_source_set_module(u->source, m); pa_source_set_description(u->source, t = pa_sprintf_malloc("Solaris PCM on '%s'", p)); pa_xfree(t); pa_source_set_asyncmsgq(u->source, u->thread_mq.inq); pa_source_set_rtpoll(u->source, u->rtpoll); u->source->flags = PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|PA_SOURCE_HW_VOLUME_CTRL; u->source->refresh_volume = 1; } else u->source = NULL; if (mode != O_RDONLY) { u->sink = pa_sink_new(m->core, __FILE__, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss, &map); pa_assert(u->sink); u->sink->userdata = u; u->sink->parent.process_msg = sink_process_msg; pa_sink_set_module(u->sink, m); pa_sink_set_description(u->sink, t = pa_sprintf_malloc("Solaris PCM on '%s'", p)); pa_xfree(t); pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); pa_sink_set_rtpoll(u->sink, u->rtpoll); u->sink->flags = PA_SINK_HARDWARE|PA_SINK_LATENCY|PA_SINK_HW_VOLUME_CTRL; u->sink->refresh_volume = 1; u->sink->refresh_mute = 1; } else u->sink = NULL; pa_assert(u->source || u->sink); u->sig = pa_signal_new(SIGPOLL, sig_callback, u); pa_assert(u->sig); ioctl(u->fd, I_SETSIG, S_MSG); if (!(u->thread = pa_thread_new(thread_func, u))) { pa_log("Failed to create thread."); goto fail; } /* Read mixer settings */ if (u->source) pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->source), PA_SOURCE_MESSAGE_GET_VOLUME, &u->source->volume, 0, NULL); if (u->sink) { pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_VOLUME, &u->sink->volume, 0, NULL); pa_asyncmsgq_send(u->thread_mq.inq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_GET_MUTE, &u->sink->muted, 0, NULL); } if (u->sink) pa_sink_put(u->sink); if (u->source) pa_source_put(u->source); pa_modargs_free(ma); return 0; fail: if (u) pa__done(m); else if (fd >= 0) close(fd); if (ma) pa_modargs_free(ma); return -1; }